<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>SLOG</title>
    <link>https://ooo-k.tistory.com/</link>
    <description>BLOG that I Write because I'm bored</description>
    <language>ko</language>
    <pubDate>Tue, 4 Aug 2026 18:48:49 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>宋白手</managingEditor>
    <image>
      <title>SLOG</title>
      <url>https://tistory1.daumcdn.net/tistory/4554091/attach/bbc0793cdd0a419ab22fba2d8c09a1a0</url>
      <link>https://ooo-k.tistory.com</link>
    </image>
    <item>
      <title>shp 파일 JSON으로 변환하기</title>
      <link>https://ooo-k.tistory.com/463</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. mapshaper 사이트 접속&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://mapshaper.org/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://mapshaper.org/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1756339127077&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;mapshaper&quot; data-og-description=&quot;&quot; data-og-host=&quot;mapshaper.org&quot; data-og-source-url=&quot;https://mapshaper.org/&quot; data-og-url=&quot;https://mapshaper.org/&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://mapshaper.org/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://mapshaper.org/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;mapshaper&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;mapshaper.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2. 파일첨부&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;.dbf .shp .shx 파일 모두 첨부&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;623&quot; data-origin-height=&quot;216&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cqrfvr/btsP73T91bv/fGzJAPv3kcakBLrZ4eY1IK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cqrfvr/btsP73T91bv/fGzJAPv3kcakBLrZ4eY1IK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cqrfvr/btsP73T91bv/fGzJAPv3kcakBLrZ4eY1IK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcqrfvr%2FbtsP73T91bv%2FfGzJAPv3kcakBLrZ4eY1IK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;623&quot; height=&quot;216&quot; data-origin-width=&quot;623&quot; data-origin-height=&quot;216&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. Simplify&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 우측 상단 Simplify 클릭&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. Visvlingam / weighted area 선택, Apply 클릭&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 게이지 조절&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;281&quot; data-origin-height=&quot;201&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CzsOz/btsP8iRwddr/r6MGAAScDozDK59s2DsHT0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CzsOz/btsP8iRwddr/r6MGAAScDozDK59s2DsHT0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CzsOz/btsP8iRwddr/r6MGAAScDozDK59s2DsHT0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCzsOz%2FbtsP8iRwddr%2Fr6MGAAScDozDK59s2DsHT0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;281&quot; height=&quot;201&quot; data-origin-width=&quot;281&quot; data-origin-height=&quot;201&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;506&quot; data-origin-height=&quot;37&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cr3k1h/btsP728Jp3n/djYZUYqvFQc47M4Wskgv2K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cr3k1h/btsP728Jp3n/djYZUYqvFQc47M4Wskgv2K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cr3k1h/btsP728Jp3n/djYZUYqvFQc47M4Wskgv2K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcr3k1h%2FbtsP728Jp3n%2FdjYZUYqvFQc47M4Wskgv2K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;506&quot; height=&quot;37&quot; data-origin-width=&quot;506&quot; data-origin-height=&quot;37&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4. 파일 저장&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 우측 상단 Export 클릭&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. GeoJSON 선택&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. Export&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;303&quot; data-origin-height=&quot;340&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xT8Io/btsP879xNps/UZDtxQwCGN1GEzwYkV4KiK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xT8Io/btsP879xNps/UZDtxQwCGN1GEzwYkV4KiK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xT8Io/btsP879xNps/UZDtxQwCGN1GEzwYkV4KiK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxT8Io%2FbtsP879xNps%2FUZDtxQwCGN1GEzwYkV4KiK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;303&quot; height=&quot;340&quot; data-origin-width=&quot;303&quot; data-origin-height=&quot;340&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;인코딩이 깨져서 나올 때&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파일 오픈 시 옵션을 입력해줘야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 파일 첨부 전 with advanced options 체크&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 파일 첨부 (.dbf .shp .shx 파일 모두 첨부)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. input 창에 encoding=cp949 입력&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. Submit&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;344&quot; data-origin-height=&quot;257&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/K8bXi/btsP7uxCsN4/NzUFRqisWBoQVOiKJnr160/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/K8bXi/btsP7uxCsN4/NzUFRqisWBoQVOiKJnr160/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/K8bXi/btsP7uxCsN4/NzUFRqisWBoQVOiKJnr160/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FK8bXi%2FbtsP7uxCsN4%2FNzUFRqisWBoQVOiKJnr160%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;344&quot; height=&quot;257&quot; data-origin-width=&quot;344&quot; data-origin-height=&quot;257&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;310&quot; data-origin-height=&quot;195&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cftfl1/btsQakAtmxD/ZLsRl7VK7T2XWa7MiJKFgK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cftfl1/btsQakAtmxD/ZLsRl7VK7T2XWa7MiJKFgK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cftfl1/btsQakAtmxD/ZLsRl7VK7T2XWa7MiJKFgK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcftfl1%2FbtsQakAtmxD%2FZLsRl7VK7T2XWa7MiJKFgK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;310&quot; height=&quot;195&quot; data-origin-width=&quot;310&quot; data-origin-height=&quot;195&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;좌표계 문제 (GeoJSON은&amp;nbsp;기본적으로&amp;nbsp;EPSG:4326&amp;nbsp;/&amp;nbsp;WGS84&amp;nbsp;사용) &lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GeoJSON 내보낼 때 좌표계를 EPSG:4326 (WGS84)로 변환해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 우측 상단 Console 클릭&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 좌측에 열린 shell 창에 아래 명령어 입력&lt;/p&gt;
&lt;pre id=&quot;code_1756340842156&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-proj from=epsg:5179 wgs84
# 또는
-proj from=epsg:5179 to=epsg:4326&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>STUDY/etc</category>
      <category>dbf</category>
      <category>JSON</category>
      <category>Path</category>
      <category>Shape</category>
      <category>SHP</category>
      <category>shx</category>
      <category>구</category>
      <category>동</category>
      <category>지도</category>
      <category>행정구역</category>
      <author>宋白手</author>
      <guid isPermaLink="true">https://ooo-k.tistory.com/463</guid>
      <comments>https://ooo-k.tistory.com/463#entry463comment</comments>
      <pubDate>Thu, 28 Aug 2025 09:36:19 +0900</pubDate>
    </item>
    <item>
      <title>forEach와 Promise.all</title>
      <link>https://ooo-k.tistory.com/462</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;ForEach의 동작&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 예시 프로그램을 하나 보겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1738759591578&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function test() {
  const testFunction = num =&amp;gt; new Promise((resolve) =&amp;gt; setTimeout(() =&amp;gt; resolve(`${num}`), num));
  const list = [3000, 2000, 3000, 4000, 1000, 1000, 2000, 3000, 1000, 1000];
  
  list.forEach( val =&amp;gt; {
    const result = testFunction(val);
    result.then(cosole.log);
  })
}

test();&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;list 에는 순서대로 timeout의 값들이 들어가 있고, forEach를 통해 순회하면서 testFunction을 실행하여 해당 결과를 출력해주는 프로그램이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;순서대로 반복한다는 점에서 개발자는 3000, 2000, 3000, 4000, 1000, 1000, 2000, 3000, 1000, 1000 의 순서대로 결과가 출력된다는 것을 예측할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;416&quot; data-origin-height=&quot;273&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/YyFXz/btsL7u83UM1/ijvNrWEoZKgKjRGoKrRjPK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/YyFXz/btsL7u83UM1/ijvNrWEoZKgKjRGoKrRjPK/img.png&quot; data-alt=&quot;https://velog.io/@0709/forEach%EC%99%80-Promise.all&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/YyFXz/btsL7u83UM1/ijvNrWEoZKgKjRGoKrRjPK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FYyFXz%2FbtsL7u83UM1%2FijvNrWEoZKgKjRGoKrRjPK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;416&quot; height=&quot;273&quot; data-origin-width=&quot;416&quot; data-origin-height=&quot;273&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://velog.io/@0709/forEach%EC%99%80-Promise.all&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 순서가 이상하다. 숫자가 작은 것부터 큰 것 순으로 마치 정렬된 것 처럼 결과가 출력되었다.&lt;/p&gt;
&lt;pre id=&quot;code_1738759709157&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Array.prototype.forEach = function (callback) {
  for (let index = 0; index &amp;lt; this.length; index++ ) {
    callback(this[index], index, this);
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;forEach는 해당 코드와 같이 동작한다. list의 요소를 순회하면서 callback 함수를 '호출' 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;callback 함수에 비동기 로직이 존재한다면? 이전 callback 함수의 결과를 받지도 않고 다음 callback을 호출하기 때문에 순서가 지켜질 수 없는 구조다. 그럼 이전 프로그램의 문제를 보겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;forEach문은 다음과 같이 콜백함수 내부에서 testFunction을 호출한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;testFunction(3000); -&amp;gt; 콜백 함수를 '호출'만 할 뿐 결과를 받지 않고 다음 testFunction 실행&lt;br /&gt;testFunction(2000); -&amp;gt; 동일&lt;br /&gt;testFunction(3000); -&amp;gt; 동일&lt;br /&gt;testFunction(4000); -&amp;gt; ...&lt;br /&gt;testFunction(1000);&lt;br /&gt;testFunction(1000);&lt;br /&gt;testFunction(2000);&lt;br /&gt;testFunction(3000);&lt;br /&gt;testFunction(1000);&lt;br /&gt;testFunction(1000);&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 10번의 testFunction이 '호출' 된다. 다만 호출만 하고 다음 호출로 넘어가기 때문에 이 열번의 testFunction은 '&lt;b&gt;거의&lt;/b&gt;' 동시에 (완벽한 동시는 아님) 실행된다. 그래서 시간 순서대로 결과가 출력된 것을 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 우리는 '호출 순서' = '결과 순서' 가 동일하기를 원한다. 프로그램을 수정한다.&lt;/p&gt;
&lt;pre id=&quot;code_1738759982276&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;async function test() {
  const testFunction = (num) =&amp;gt; new Promise((resolve) =&amp;gt; setTimeout(()=&amp;gt; resolve(`${num}`), num));
  const list = [3000, 2000, 3000, 4000, 1000, 1000, 2000, 3000, 1000, 1000];
  
  for(let i=0; i&amp;lt;list.length; i++) {
    const result = await testFunction(list[i]);
    console.log(result);
  }
}

test();&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 forEach가 아닌 단순 for문으로 변경했다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;289&quot; data-origin-height=&quot;278&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bYoZc0/btsL6VlK5Yu/oXjySoOOuVBI4xg7cMdigk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bYoZc0/btsL6VlK5Yu/oXjySoOOuVBI4xg7cMdigk/img.png&quot; data-alt=&quot;https://velog.io/@0709/forEach%EC%99%80-Promise.all&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bYoZc0/btsL6VlK5Yu/oXjySoOOuVBI4xg7cMdigk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbYoZc0%2FbtsL6VlK5Yu%2FoXjySoOOuVBI4xg7cMdigk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;289&quot; height=&quot;278&quot; data-origin-width=&quot;289&quot; data-origin-height=&quot;278&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://velog.io/@0709/forEach%EC%99%80-Promise.all&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 원하는 순서대로 출력된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 코드는 반복문의 각 단계에서 testFunction의 결과를 받을 때까지 기다리기(await) 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 뭔가 좀 아쉽다. 위의 forEach 에서 처럼 testFunction 호출은 '거의' 동시에 해놓고 결과는 순서대로 받아올 수 있다면 더 효율적이지 않을까 하는 고민이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;for문으로 해결한 방식으로는 3+2+3+4+1+1+2+3+1+1=21 초만큼 기다려야 하지만, 만약 위의 방식이 가능하다면 4초만 기다로고도 모든 결과를 받아올 수 있기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로그램을 조금 더 수정한다.&lt;/p&gt;
&lt;pre id=&quot;code_1738760191645&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function test() {
  const testFunction = (num) =&amp;gt; new Promise((resolve) =&amp;gt; setTimeout(()=&amp;gt; resolve(`${num}`), num));
  const list = [3000, 2000, 3000, 4000, 1000, 1000, 2000, 3000, 1000, 1000];
  
  Promise.all(list.map(element) =&amp;gt; testFunction(element))
    .then(console.log)
    .catch(console.log);
}

test();&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 코드는 map 메소드를 활용하여 testFunction의 반환값인 Promise 객체를 가지고 있게 된다. 다만 결과값을 아직 가져오지 못햇다면 pending 상태가 된다. 하지만 호출 순서는 보장되기 때문에 결과값을 가져온 순서에는 영향을 받지 않게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Promise.all은 인자로 받은 Promise 배열이 모두 resolve 상태가 되면 then의 콜백함수를 실행하게 된다. 그래서 결과를 보면&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;557&quot; data-origin-height=&quot;37&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Ba8Ot/btsL9sooRXt/94KOYvrk6Iv6F7XmoPXkT1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Ba8Ot/btsL9sooRXt/94KOYvrk6Iv6F7XmoPXkT1/img.png&quot; data-alt=&quot;https://velog.io/@0709/forEach%EC%99%80-Promise.all&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Ba8Ot/btsL9sooRXt/94KOYvrk6Iv6F7XmoPXkT1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBa8Ot%2FbtsL9sooRXt%2F94KOYvrk6Iv6F7XmoPXkT1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;557&quot; height=&quot;37&quot; data-origin-width=&quot;557&quot; data-origin-height=&quot;37&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://velog.io/@0709/forEach%EC%99%80-Promise.all&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4초만에 결과를 얻어올 수 있었을 뿐만 아니라 순서까지 보장된다. Promise 객체를 순서대로 배열에 저장했기 때문에 가능한 일이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Promise.all -&amp;gt; map 메소드 활용 패턴과 forEach문의 동작은 기억하면 좋겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://velog.io/@0709/forEach%EC%99%80-Promise.all&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://velog.io/@0709/forEach%EC%99%80-Promise.all&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1738759473861&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;forEach와 Promise.all&quot; data-og-description=&quot;forEach의 동작과 Promise.all에 대해 고민한 개발 일지&quot; data-og-host=&quot;velog.io&quot; data-og-source-url=&quot;https://velog.io/@0709/forEach%EC%99%80-Promise.all&quot; data-og-url=&quot;https://velog.io/@0709/forEach와-Promise.all&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bWlDQm/hyYcfw4uNe/kQhgZtmA5Ax4ba3lukkiMk/img.png?width=950&amp;amp;height=500&amp;amp;face=0_0_950_500,https://scrap.kakaocdn.net/dn/cIzAmU/hyX71gc8dY/SfeALLFk8yNJpoXXnj7fsk/img.png?width=720&amp;amp;height=720&amp;amp;face=285_195_463_390,https://scrap.kakaocdn.net/dn/44tFW/hyX7XdMcge/fvvZ8M44DejrHBSay99XwK/img.png?width=416&amp;amp;height=273&amp;amp;face=0_0_416_273&quot;&gt;&lt;a href=&quot;https://velog.io/@0709/forEach%EC%99%80-Promise.all&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://velog.io/@0709/forEach%EC%99%80-Promise.all&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bWlDQm/hyYcfw4uNe/kQhgZtmA5Ax4ba3lukkiMk/img.png?width=950&amp;amp;height=500&amp;amp;face=0_0_950_500,https://scrap.kakaocdn.net/dn/cIzAmU/hyX71gc8dY/SfeALLFk8yNJpoXXnj7fsk/img.png?width=720&amp;amp;height=720&amp;amp;face=285_195_463_390,https://scrap.kakaocdn.net/dn/44tFW/hyX7XdMcge/fvvZ8M44DejrHBSay99XwK/img.png?width=416&amp;amp;height=273&amp;amp;face=0_0_416_273');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;forEach와 Promise.all&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;forEach의 동작과 Promise.all에 대해 고민한 개발 일지&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;velog.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://velog.io/@hanameee/%EB%B0%B0%EC%97%B4%EC%97%90-%EB%B9%84%EB%8F%99%EA%B8%B0-%EC%9E%91%EC%97%85%EC%9D%84-%EC%8B%A4%EC%8B%9C%ED%95%A0-%EB%95%8C-%EC%95%8C%EC%95%84%EB%91%90%EB%A9%B4-%EC%A2%8B%EC%9D%84%EB%B2%95%ED%95%9C-%EC%9D%B4%EC%95%BC%EA%B8%B0%EB%93%A4&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://velog.io/@hanameee/%EB%B0%B0%EC%97%B4%EC%97%90-%EB%B9%84%EB%8F%99%EA%B8%B0-%EC%9E%91%EC%97%85%EC%9D%84-%EC%8B%A4%EC%8B%9C%ED%95%A0-%EB%95%8C-%EC%95%8C%EC%95%84%EB%91%90%EB%A9%B4-%EC%A2%8B%EC%9D%84%EB%B2%95%ED%95%9C-%EC%9D%B4%EC%95%BC%EA%B8%B0%EB%93%A4&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1738760375421&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;배열에 비동기 작업을 실시할 때 알아두면 좋은 이야기들&quot; data-og-description=&quot;프론트엔드 인턴 면접에서 비동기 작업 관련 질문 대답 못한 뒤 외양간 뚝딱뚝딱 고치는 이야기.&quot; data-og-host=&quot;velog.io&quot; data-og-source-url=&quot;https://velog.io/@hanameee/%EB%B0%B0%EC%97%B4%EC%97%90-%EB%B9%84%EB%8F%99%EA%B8%B0-%EC%9E%91%EC%97%85%EC%9D%84-%EC%8B%A4%EC%8B%9C%ED%95%A0-%EB%95%8C-%EC%95%8C%EC%95%84%EB%91%90%EB%A9%B4-%EC%A2%8B%EC%9D%84%EB%B2%95%ED%95%9C-%EC%9D%B4%EC%95%BC%EA%B8%B0%EB%93%A4&quot; data-og-url=&quot;https://velog.io/@hanameee/배열에-비동기-작업을-실시할-때-알아두면-좋을법한-이야기들&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bmZtkQ/hyX7Th6ghR/13UKErnEJleQHx29RgYEkK/img.png?width=1080&amp;amp;height=563&amp;amp;face=0_0_1080_563,https://scrap.kakaocdn.net/dn/jJIKE/hyYcbOYMDD/9Hdpxht7HaWwh2HWOfIXik/img.png?width=1080&amp;amp;height=563&amp;amp;face=0_0_1080_563,https://scrap.kakaocdn.net/dn/cwgHZE/hyX7ZbDXmA/BSUz6YFE6Qo7kJJEqfXUEk/img.png?width=1080&amp;amp;height=563&amp;amp;face=0_0_1080_563&quot;&gt;&lt;a href=&quot;https://velog.io/@hanameee/%EB%B0%B0%EC%97%B4%EC%97%90-%EB%B9%84%EB%8F%99%EA%B8%B0-%EC%9E%91%EC%97%85%EC%9D%84-%EC%8B%A4%EC%8B%9C%ED%95%A0-%EB%95%8C-%EC%95%8C%EC%95%84%EB%91%90%EB%A9%B4-%EC%A2%8B%EC%9D%84%EB%B2%95%ED%95%9C-%EC%9D%B4%EC%95%BC%EA%B8%B0%EB%93%A4&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://velog.io/@hanameee/%EB%B0%B0%EC%97%B4%EC%97%90-%EB%B9%84%EB%8F%99%EA%B8%B0-%EC%9E%91%EC%97%85%EC%9D%84-%EC%8B%A4%EC%8B%9C%ED%95%A0-%EB%95%8C-%EC%95%8C%EC%95%84%EB%91%90%EB%A9%B4-%EC%A2%8B%EC%9D%84%EB%B2%95%ED%95%9C-%EC%9D%B4%EC%95%BC%EA%B8%B0%EB%93%A4&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bmZtkQ/hyX7Th6ghR/13UKErnEJleQHx29RgYEkK/img.png?width=1080&amp;amp;height=563&amp;amp;face=0_0_1080_563,https://scrap.kakaocdn.net/dn/jJIKE/hyYcbOYMDD/9Hdpxht7HaWwh2HWOfIXik/img.png?width=1080&amp;amp;height=563&amp;amp;face=0_0_1080_563,https://scrap.kakaocdn.net/dn/cwgHZE/hyX7ZbDXmA/BSUz6YFE6Qo7kJJEqfXUEk/img.png?width=1080&amp;amp;height=563&amp;amp;face=0_0_1080_563');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;배열에 비동기 작업을 실시할 때 알아두면 좋은 이야기들&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;프론트엔드 인턴 면접에서 비동기 작업 관련 질문 대답 못한 뒤 외양간 뚝딱뚝딱 고치는 이야기.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;velog.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>STUDY/JavaScript</category>
      <category>Async</category>
      <category>await</category>
      <category>foreach</category>
      <category>promise.all</category>
      <category>비동기</category>
      <author>宋白手</author>
      <guid isPermaLink="true">https://ooo-k.tistory.com/462</guid>
      <comments>https://ooo-k.tistory.com/462#entry462comment</comments>
      <pubDate>Wed, 5 Feb 2025 22:02:27 +0900</pubDate>
    </item>
    <item>
      <title>깃(Git) 개념과 상황별 팁</title>
      <link>https://ooo-k.tistory.com/461</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;기본 개념과 명령어&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;초기화&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;깃을 올바로 사용하려면 깃이 파일의 변경 내용을 추적하는 방식을 이해하는 것이 무척 중요하다. 그렇지 않고 백업 용도로만 깃을 사용하면 장님이 코끼리 만지는 것처럼 딱 그만큼만 알게 되기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;깃은 폴더의 어떤 파일이라도 모두 트래킹 할 수 있다. 원하는 폴더로 이동해 깃 초기화 커맨드부터 시작한다.&lt;/p&gt;
&lt;pre id=&quot;code_1738416458510&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ git init&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;.git 이라는 이름의 숨김 폴더가 하나 생긴다. 이것을 저장소라고 하는데 깃은 이 폴더의 모든 변경 내용을 여기에 저장한다. 이 파일을 지우면 더 이상 깃으로 폴더의 변경사항을 추적할 수 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;스테이징&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;깃이 파일의 변경 내역을 저장하는데 곧바로 저장하는 것이 아니라 스테이징이라는 단계를 거친다. 스테이징은 변경사항 중에서 저장하고 싶은 부분만 선택해 임시로 저장하는 갠며이다. 코드를 변경하고 깃 상태를 먼저 봐보자.&lt;/p&gt;
&lt;pre id=&quot;code_1738760613322&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ git status&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #666666; text-align: left;&quot;&gt;Untracked files:&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #666666; text-align: left;&quot;&gt;&amp;nbsp; (use &quot;git add &amp;lt;file&amp;gt;&amp;middot;&amp;middot;&amp;middot;&quot; to include in what will be committed)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #666666; text-align: left;&quot;&gt;&amp;nbsp; file.txt&lt;/span&gt;&lt;i&gt;&lt;/i&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;폴더의 현재 변경 상태를 보는 명령어다. 폴더에는 file.txt 파일이 있는데 아직 깃이 이 파일을 트래킹하지 않아서 &quot;Untracked files&quot; 목록에 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추적하고 싶은 파일을 스테이지에 넣기 위해서는 변경된 파일을 선택하거나,&lt;/p&gt;
&lt;pre id=&quot;code_1738416645874&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ git add file.txt&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;폴더의 전체 변경 사항을 지정할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1738416664048&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ git add .&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스테이징 된 파일은 이렇게 커밋 직전 상태로 변경된다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;&lt;i&gt;$ git status&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;Changes to be committed:&lt;br /&gt;&amp;nbsp; new file:&amp;nbsp; file.txt&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;커밋&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;깃이 폴더의 변경 내용을 저장하는 단위를 커밋 `commit` 이라고 부르는데, 이처럼 먼저 스테이징 상태에 두어야만 비로소 커밋을 만들 수 있다. 스테이지에 있는 내용으로 커밋을 만들려면 `commit` 명령어를 사용한다.&lt;/p&gt;
&lt;pre id=&quot;code_1738420494748&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ git commit&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본 에디터가 열리고 변경 내용을 기록할 수 있는 입력 화면이 나온다. 변경 내용을 설명할 수 있는 텍스트를 입력하고 저장하면 커밋이 생성된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;에디터를 열지않고 터미널에서 바로 메세지를 입력할 수 있는 `-m` 옵션도 자주 사용한다.&lt;/p&gt;
&lt;pre id=&quot;code_1738420570963&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ git commit -m &quot;여기에 커밋메세지를 입력합니다.&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;매번 변경사항을 스테이징하고 커밋하는게 번거롭다면 `-a` 옵션을 사용하자. 신규 파일을 제외하고 트래킹 하는 모든 파일의 변경사항을 스테이징함과 동시에 커밋을 만들 수 있는 옵션이다. `-m` 과 함께 사용할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1738420644599&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ git commit -am &quot;스테이징과 커밋을 한번에!&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;커밋을 만들지 않고 이전 커밋에 변경사항을 추가하고 싶은 경우도 있다. 가끔 이전 커밋에 미쳐 포함하지 못한 코드가 있을 수 있는데, 이전 커밋에 현재 변경 내용을 추가할 때는 `--amend` 옵션을 사용한다.&lt;/p&gt;
&lt;pre id=&quot;code_1738422805958&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ git commit --amend&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;에디터가 뜨면서 마지막 커밋 메시지를 수정하는 화면이 나온다. 저장하고 에디터를 닫으면 이전 커밋에 변경 내용이 추가된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;로그&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스테이징을 거쳐 커밋한 결과를 어떻게 볼 수 있을까? 깃은 커밋 목록을 로그(log)라는 형식으로 볼 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1738422870262&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ git log&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;commit 5ede63b20ee6237c345a7595d6f353c86eb3388b (HEAD -&amp;gt; master)&lt;br /&gt;Author:&amp;nbsp; &amp;nbsp;name &amp;lt;mail@mail.com&amp;gt;&lt;br /&gt;Date:&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Mon Feb 3 09:36:02 2020 +0900&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; 두번째 커밋입니다.&lt;br /&gt;&lt;br /&gt;commit 5ede63b20ee6237c345a7595d6f353c86eb3388b (HEAD -&amp;gt; master)&lt;br /&gt;Author:&amp;nbsp; &amp;nbsp;name &amp;lt;mail@mail.com&amp;gt;&lt;br /&gt;Date:&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Mon Feb 3 09:36:02 2020 +0900&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;첫번째 커밋입니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두 개의 커밋이 있는 로그다. 각 커밋을 식별할 수 있는 커밋 해쉬값이 먼저 나온다. 그 다음 커밋 작성자와 작성일자, 마지막으로 변경 내용을 기록한 커밋 메세지를 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;커밋에 변경 내용이 반영되었는지 보려면 `show` 명령어를 사용한다.&lt;/p&gt;
&lt;pre id=&quot;code_1738423035859&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ git show&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&amp;nbsp; 테스트 파일입니다.&lt;br /&gt;-수정함&lt;br /&gt;+지우고 수정함&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;삭제한 라인은 앞에 `-`를, 추가한 라인은 `+`로 표시한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특정 커밋의 변경사항을 보고 싶다면 로그에 있는 커밋 해쉬로 볼 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1738423089509&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ git show 5ede63b20ee6237c345a7595d6f353c86eb3388b&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;브랜치&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;깃에서 중요한 또 하나의 개념은 브랜치(branch) 이다. 로그에서 보는 것처럼 깃이 관리하는 변경 이력은 마치 자라나는 나무같다. 그래서 &quot;깃 트리&quot;라고 하는지도 모르겠다. 나무는 성장하면서 또 다른 가지를 뻗어 내는데, 깃도 이런 방식의 가지를 만들 수 있고 가지를 브랜치라고 부른다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;브랜치를 만드는 이유는 뭘까? 지금하고 있는 작업과 성격이 다른 작업을 할 때 브랜치를 만든다. 가령 A 기능을 만들다가 B 기능을 만들어야 한다면 브랜치를 새로 만들어 B를 개발하는 방식이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;깃은 기본적으로 main 이라는 이름의 브랜치를 하나 가지고 있다. `branch` 명령어로 브랜치 목록을 확인하자.&lt;/p&gt;
&lt;pre id=&quot;code_1738756127763&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ git branch&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;* main&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 지금 작업하고 있는 내용과 성격이 다른 작업을 하기 위해 feature 라는 이름의 브랜치를 하나 만들어 보자. `branch` 명령어를 사용할 때 두 개 브랜치 명을 전달하는데 &quot;생성할 브랜치 명&quot; &quot;기준 브랜치 명&quot; 순서다.&lt;/p&gt;
&lt;pre id=&quot;code_1738756185722&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ git branch feature master
$ git branch&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&amp;nbsp; &amp;nbsp;feature&lt;br /&gt;* main&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;feature 브랜치가 추가되어 총 두 개의 브랜치가 있다. 여전히 현재 브랜치는 앞에 별표(*)가 있는 main 브랜치다. 새로 만든 브랜치로 이동하고 싶은데 깃에서 브랜치간의 선택은 &lt;b&gt;체크아웃한다(checkout)&lt;/b&gt; 라고 표현한다.&lt;/p&gt;
&lt;pre id=&quot;code_1738756258956&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ git checkout feature
$ git branch&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;* feature&lt;br /&gt;&amp;nbsp; &amp;nbsp;main&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 둘을 한번에 하려면, 즉 브랜치를 만들면서 선택하려면 기준 브랜치에서 `-b` 옵션을 주고 체크아웃 하는 방법이 있다. 예를 들어 main 브랜치에서 feature 브랜치를 만들고 체크아웃 하려면 이렇게 하면된다.&lt;/p&gt;
&lt;pre id=&quot;code_1738756313664&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ git checkout -b feature&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;feature 브랜치에서 개발하고 커밋을 계속 만든 뒤 다음 단계는 뭘까? 브랜치에 만든 커밋들을 다시 원래 브랜치인 main에 반영해야 한다. 이것을 &lt;b&gt;병합(merge)&lt;/b&gt;이라고 부른다.&lt;/p&gt;
&lt;pre id=&quot;code_1738756365211&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ git checkout main
&amp;amp; git merge feature&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기준이 되는 main 브랜치로 이동한 뒤, feature 브랜치를 main에 머지한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;헤드&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;브랜치간에 이동하다 보면 현재 내가 어느 브랜치에서 작업하는지 알아야 한다. 간단하게는 브랜치 목록에서 현재 어느 브랜치인지 알 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1738756415401&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ git branch&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&amp;nbsp; &amp;nbsp;feature&lt;br /&gt;* main&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞에 별표(*) 된 것이 현재 브랜치다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위치를 좀 더 정확하게 보여주는 정보가 있는데 바로 &lt;b&gt;머리(HEAD)&lt;/b&gt; 라고 부르는 것이다. 헤드는 여러 개 가지로 뻗어있는 브랜치와 커밋 목록에서 현재 위치를 나타낸다.&lt;/p&gt;
&lt;pre id=&quot;code_1738756467993&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ git log&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;commit 23427f8fb1baa80a5f0c9f974ba16dd0212edd69&amp;nbsp;(HEAD -&amp;gt; main)&lt;br /&gt;commit d4b18ac8dc8f1e29a6082163b9329ffabd5bca96&amp;nbsp;(feature)&lt;br /&gt;commit 18383c3d504208864ec73e7845d126a4824a43d6&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;main 브랜치 끝에 헤드가 표시되어 있다. 지금 작업하고 있는 위치다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;체크아웃 하면서 브랜치를 이동할 때 마다 헤드는 수시로 변경된다. 뿐만 아니라 특정 커밋으로 체크아웃 할 수 있는데 이 때도 헤드는 그 커밋으로 이동한다.&lt;/p&gt;
&lt;pre id=&quot;code_1738756568112&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ git checkout 18383c3d504208864ec73e7845d126a4824a43d6
$ git log&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;* 23427f8fb1baa80a5f0c9f974ba16dd0212edd69 (main)&lt;br /&gt;* d4b18ac8dc8f1e29a6082163b9329ffabd5bca96 (feature)&lt;br /&gt;* 18383c3d504208864ec73e7845d126a4824a43d6 (HEAD)&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;상황별 팁&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 정도로 깃에 대해 개념을 간단히 정리하고, 상황별로 깃 명령어를 어떻게 사용할 수 있는지 알아보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;1. 필요한 라인만 커밋하고 싶어요&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보통 변경된 &lt;b&gt;파일&lt;/b&gt;을 스테이징한 뒤 이것을 커밋하기 때문에 커밋은 파일단위로 묶이게 된다. 의미있는 커밋 메세지를 유지하려다보면, &lt;b&gt;파일의 라인&lt;/b&gt; 단위로 변경사항을 묶고 싶을 경우가 있다. 지금까지 이런 식의 커밋을 위해 변경된 내용을 복사 붙여넣기 했다면 아래 방식도 사용해 보길 바란다.&lt;/p&gt;
&lt;pre id=&quot;code_1738756681117&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ git add -p&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;변경한 라인만 스테이지에 넣는 것이 바로 `-p` 옵션이다. 이렇게 하면 변경된 파일을 하나씩 열어 스테이징 할지 말지 결정하면 된다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&amp;nbsp; &amp;nbsp;기존 코드입니다.&lt;br /&gt;+ 여기는 나중에 커밋하고요&lt;br /&gt;&amp;nbsp; &amp;nbsp;기존 코드입니다.&lt;br /&gt;&lt;br /&gt;_&lt;br /&gt;+ 이 부분을 커밋하고 싶어요.&lt;br /&gt;+ 이곳도 나중에 커밋합니다.&lt;br /&gt;Stage this hunk [y,n,q,a,d,s,e,?]? s&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;`s` (split)을 입력하면 변경 단위를 더 세밀하게 쪼갠다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&amp;nbsp; &amp;nbsp;기존 코드입니다.&lt;br /&gt;+ 여기는 나중에 커밋하고요&lt;br /&gt;&amp;nbsp; &amp;nbsp;기존 코드입니다.&lt;br /&gt;&amp;nbsp; &amp;nbsp;Stage this hunk [y,n,q,a,d,j,J,g,/,e,?]? n&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존 코드 기준으로 변경사항을 분할해서 보여준다. 이 부분을 스테이징에서 제외하려면 `n` (no) 을 입력하고 다음 분할 부분으로 넘어간다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&amp;nbsp; &amp;nbsp;기존 코드입니다.&lt;br /&gt;+ 이 부분을 커밋하고 싶어요.&lt;br /&gt;+ 이 곳도 나중에 커밋합니다.&lt;br /&gt;Stage this hunk [y,n,q,a,d,K,g,/,e,?]? e&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;변경된 코드가 연속으로 있을 경우 깃은 스스로 코드를 분할할 수 없다. 이러한 경우에는 `e` (edit)를 입력하고 편집 모드로 들어가 직접 스테이징할 라인을 선별할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;# Manual hunk edit mode -- see bottom for a quick guide.&lt;br /&gt;4&amp;nbsp; &amp;nbsp;기존 코드입니다.&lt;br /&gt;5&lt;br /&gt;7 + 이 부분을 커밋하고 싶어요.&lt;br /&gt;8 + 이 곳도 나중에 커밋합니다. --&amp;gt; 스테이징에서 제외하려면 이 라인을 삭제한다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추가된 코드 중 7번 라인만 스테이징 하려고 한다. 이 부분을 남겨두고 아래 8번 라인만 제거하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 선택적으로 스테이징한 뒤 커밋하면 훨씬 의미있는 커밋을 만들 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 이걸 커밋으로 생성해야 하는데 커밋에 `-v` (verbose) 옵션을 주면 스테이징된 부분을 자세히 볼 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1738757033888&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ git commit -v&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;2. 커밋의 변경내용을 자세히 보고 싶어요&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;깃은 파일의 변경 내용과 요약 메세지, 작성자, 작성일 등의 메타 정보를 모두 합쳐서 하나의 커밋을 만들어 낸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;`log` 명령어로 간단한 커밋 정보를 볼 수 있었다면 `show` 명령어로 더 자세한 내용을 조회할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1738757094157&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ git show&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&amp;nbsp; &amp;nbsp;기존 코드입니다.&lt;br /&gt;- 여기는 삭제될 부분이에요.&lt;br /&gt;+ 여기를 마지막에 추가했어요&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존 내용에서 삭제/추가한 부분으로 나누어 표시한다. 삭제한 줄은 `-`로, 추가한 줄은 `+`로 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 깃 트리에 많은 커밋 중에 어떤 커밋의 내용을 보여주는 걸까? `show`는 기본적으로 HEAD가 가리키고 있는 커밋의 정보를 조회한다. 특정 커밋의 내용을 보려면 커밋 식별자인 &lt;b&gt;커밋해쉬&lt;/b&gt;로 식별한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1738757183771&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ git show 7ad18c6b000554ed69dbabe7344b67d8beda6915
# 혹은
$ git show 7ad18c6&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해쉬값을 사용하거나 이 값이 너무 길면 앞의 7자리만 사용해서 해쉬값에 해당하는 커밋의 변경사항을 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하나의 커밋에서 많은 파일을 변경했을 경우에는 파일별로 변경내용을 요약해서 볼 수도 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1738757218802&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ git show --stat&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;두개 파일을 수정합니다.&lt;br /&gt;&lt;br /&gt;file.txt&amp;nbsp; &amp;nbsp; &amp;nbsp;|&amp;nbsp; 5 +++--&lt;br /&gt;file2.txt&amp;nbsp; &amp;nbsp;|&amp;nbsp; 1 +&lt;br /&gt;2 files changed, 4 insertions(+), 2 deleteions(-)&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;file.txt는 5개 라인을 변경했는데 3줄을 추가하고 2줄을 삭제했다. file2.txt는 1줄을 추가했다. 총 2개 파일을 변경했고 4줄 추가하고 2줄 삭제한 커밋이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주로 과거에 작업했던 내용을 찾아볼 때 이 명령어를 자주 사용한다. 어떤 내용을 변경했는지 라인별로 확인하고 한 커밋에 변경한 파일이 많으면 `--stat` 옵션으로 파일 목록을 확인한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런 뒤 특정 파일의 변경사항은 파일명을 지정해서 확인하는 편이다.&lt;/p&gt;
&lt;pre id=&quot;code_1738757350784&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ git show 7ad18c6 file.txt&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 커밋 내용을 자세히 볼 수 있기 때문에 웬만하면 주석은 그냥 지우는 편이다. 삭제했다는 내용의 메세지로 커밋을 저장하고 나중에 주석 대신에 삭제한 커밋을 들여다 보는 것이 코드를 비교적 가볍게 가져갈 수 있기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;3. 커밋하기는 좀 그렇고&amp;middot;&amp;middot;&amp;middot; 변경사항을 임시 저장할 수 있나요?&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;작업을 하다가 임시 저장해야 하는 상황이 있다. 커밋 메세지도 떠오르지 않고 그냥 잠깐 저장하고 다른 작업을 하고 싶을때가 그렇다. 처음에는 &quot;WIP&quot; (Work In Progress) 라는 작업중 메세지로 커밋을 만들곤 했었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 몇 년 전부터 동료들이 `stash` 명령어를 사용하는 걸 보곤 나도 무척 잘 활용하고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;숨겨두다&quot; 라는 의미의 이 명령어는 커밋하기에는 충분치 않지만 저장은 해야하는 이런 상황을 위한 것이다.&lt;/p&gt;
&lt;pre id=&quot;code_1738757498262&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ git stash&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 명령어를 실행하고 나면 현재 폴더의 변경내용이 다른 어딘가로 저장되고 변경된 내용이 파일에서 사라진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;stash도 커밋처럼 하나의 단위로 저장되는 stash 목록을 확인할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1738757541290&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ git stash list&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;stash@{0}: WIP on main: 7ad18c6 두 개 파일을 수정합니다&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 한번 더 내용을 수정하고 stash 하고 목록을 보면 추가된 stash가 기존 목록 위에 쌓인다. 마치 스택처럼 말이다.&lt;/p&gt;
&lt;pre id=&quot;code_1738757604467&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ git stash list&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;stash@{0}: WIP on main: 7ad18c6 두 개 파일을 수정합니다.&lt;br /&gt;stash@{1}: WIP on main: 7ad18c6 두 개 파일을 수정합니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;임시 저장한 변경 내용을 되돌리려면 팝(`pop`)으로 꺼낸다.&lt;/p&gt;
&lt;pre id=&quot;code_1738757650469&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ git stash pop&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 임시 저장했던 변경 내용들이 파일에 다시 복구되었을 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지라 같은 업무 관리 툴로 일을 하다보면 업무 간에 스위칭이 잦은 경우가 있다. 이 때 잠시 stash로 지금 작업 내용을 저장하고 다른 업무를 보면 좀 더 코드 관리하기가 쉽다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;4. 히스토리를 예쁘게 보고 싶어요&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로그 트리 때문에 터미널에서 깃을 사용하는걸 부담스럽게 여긴다면 잠깐만 여길 봐 보시라. 깃 로그 명령어는 꽤 많은 옵션을 가지고 있다. 먼저 `--graph` 옵션으로 로그를 봐 보자.&lt;/p&gt;
&lt;pre id=&quot;code_1738757737262&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ git log --graph&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;726&quot; data-origin-height=&quot;662&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/k1ebH/btsL8l4PBG7/jcdyQwKU1ZfYf4pSgt1rN0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/k1ebH/btsL8l4PBG7/jcdyQwKU1ZfYf4pSgt1rN0/img.jpg&quot; data-alt=&quot;https://jeonghwan-kim.github.io/dev/2020/02/10/git-usage.html#%ED%97%A4%EB%93%9C&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/k1ebH/btsL8l4PBG7/jcdyQwKU1ZfYf4pSgt1rN0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fk1ebH%2FbtsL8l4PBG7%2FjcdyQwKU1ZfYf4pSgt1rN0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;726&quot; height=&quot;662&quot; data-origin-width=&quot;726&quot; data-origin-height=&quot;662&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://jeonghwan-kim.github.io/dev/2020/02/10/git-usage.html#%ED%97%A4%EB%93%9C&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;터미널에서도 그래프를 볼 수 있다는 점에 놀라웠는가? 이제 여기에다가 조금씩 그래프를 예쁘게 만들어 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보통 커밋해쉬를 다 보진 않는다. 해쉬값 전체를 사용하는 경우도 없었고 말이다. 커밋 해쉬값을 앞에 7자리만 간단히 보여주는 것이 좋겟다. `--abbrev-commit` 옵션을 추가해보자.&lt;/p&gt;
&lt;pre id=&quot;code_1738757814402&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ git log --graph --abbrev-commit&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;726&quot; data-origin-height=&quot;667&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/beTTJu/btsL8IyI90S/dW4G0XNe9OZCzTXzyAbZf0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/beTTJu/btsL8IyI90S/dW4G0XNe9OZCzTXzyAbZf0/img.jpg&quot; data-alt=&quot;https://jeonghwan-kim.github.io/dev/2020/02/10/git-usage.html#%ED%97%A4%EB%93%9C&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/beTTJu/btsL8IyI90S/dW4G0XNe9OZCzTXzyAbZf0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbeTTJu%2FbtsL8IyI90S%2FdW4G0XNe9OZCzTXzyAbZf0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;726&quot; height=&quot;667&quot; data-origin-width=&quot;726&quot; data-origin-height=&quot;667&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://jeonghwan-kim.github.io/dev/2020/02/10/git-usage.html#%ED%97%A4%EB%93%9C&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;커밋 해쉬값이 짧아져서 좀 덜 부담스럽다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하나의 로그가 좀 길다. 중요한 메세지만 남기고 로그 그래프를 더 보고 싶다면 `--pretty` 옵션을 추가 해보자.&lt;/p&gt;
&lt;pre id=&quot;code_1738757875203&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ git log --graph --abbrev-commit --pretty=oneline&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;726&quot; data-origin-height=&quot;152&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rExlB/btsL7ABnnoz/SgTVXENXkPKdlSrFqKsPF1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rExlB/btsL7ABnnoz/SgTVXENXkPKdlSrFqKsPF1/img.jpg&quot; data-alt=&quot;https://jeonghwan-kim.github.io/dev/2020/02/10/git-usage.html#%ED%97%A4%EB%93%9C&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rExlB/btsL7ABnnoz/SgTVXENXkPKdlSrFqKsPF1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrExlB%2FbtsL7ABnnoz%2FSgTVXENXkPKdlSrFqKsPF1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;726&quot; height=&quot;152&quot; data-origin-width=&quot;726&quot; data-origin-height=&quot;152&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://jeonghwan-kim.github.io/dev/2020/02/10/git-usage.html#%ED%97%A4%EB%93%9C&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;커밋 해시와 메세지만 한 줄로 나오고 더 많은 커밋 그래프를 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 브랜치와 태그를 함께 보고싶은가?&lt;/p&gt;
&lt;pre id=&quot;code_1738757919995&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ git log --graph --abbrev-commit --pretty=oneline --all&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;main 브랜치 외에도 feature 브랜치의 트리도 볼 수 있다. 뿐만 아니라 태그도 같이 표기한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;726&quot; data-origin-height=&quot;203&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bsbNs4/btsL7iOBldg/OwuKiHS3zCjFpFrWKmhE41/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bsbNs4/btsL7iOBldg/OwuKiHS3zCjFpFrWKmhE41/img.jpg&quot; data-alt=&quot;https://jeonghwan-kim.github.io/dev/2020/02/10/git-usage.html#%ED%97%A4%EB%93%9C&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bsbNs4/btsL7iOBldg/OwuKiHS3zCjFpFrWKmhE41/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbsbNs4%2FbtsL7iOBldg%2FOwuKiHS3zCjFpFrWKmhE41%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;726&quot; height=&quot;203&quot; data-origin-width=&quot;726&quot; data-origin-height=&quot;203&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://jeonghwan-kim.github.io/dev/2020/02/10/git-usage.html#%ED%97%A4%EB%93%9C&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;밋밋했던 커밋 로그가 그래픽 도구 못지 않게 훌륭해졌다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;5. 히스토리를 변경하고 싶어요&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;A 작업을 마치고 커밋, B 작업을 마치고 커밋, A' 작업을 마치고 커밋을 만들었다. 깃 로그는 A -&amp;gt; B -&amp;gt; A' 순으로 쌓이게 된다. 이왕이면 관련된 커밋을 한 곳으로 모으곳 ㅣㅍ다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지라 따위의 애자일 도구를 사용한다면 이런 경우가 자주 발생할 수 있다. 작업 번호로 커밋 메세지를 만들텐데 앞에 지라 번호를 붙여 메세지를 작성할 것이다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;* da964a1 [TASK-A] A 작업 추가함 (HEAD -&amp;gt; main)&lt;br /&gt;* 758713d [TASK-B] B 작업함&lt;br /&gt;* d323105 [TASK-A] A 작업함&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마지막 두 개의 커밋 순서를 바꾸면 작업을 이해하는데 더 좋고 의미있는 커밋이 될 것 같다. 코드의 가독성 뿐만 아니라 커밋의 가독성도 그것만큼 중요하니까 말이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리베이스 `rebase`를 이용하면 커밋 순서를 변경할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1738758141746&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ git rebase -i HEAD~3&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;HEAD를 포함한 이전 3개 커밋을 재작성(rebase) 한다는 뜻이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;에디터가 열려 커밋 목록이 나오고 여기서 순서를 변경할 수 있다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;1 pick d323105 [TASK-A] A 작업함&lt;br /&gt;2 pick 758713d [TASK-B] B 작업함&lt;br /&gt;3 pick da964a1 [TASK-A] A 작업 추가함&lt;br /&gt;4&lt;br /&gt;5 # Rebase 23427f8..da964a1 onto 23427f8 (3 commands)&lt;br /&gt;6 #&lt;br /&gt;7 # Commands:&lt;br /&gt;8 # p, pick &amp;lt;commit&amp;gt; = use commit&lt;br /&gt;9 # f, fixup &amp;lt;commit&amp;gt; = like &quot;squash&quot;, but discard this commit's log message&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 두 개의 커밋을 하나로 합치고 싶다면 마지막에 있는 'A 작업 추가함'을 2번 라인으로 옮긴다. 그리고 `pick` 대신 `fixup` 혹은 줄여서 `f`를 입력한다. 그럼 이 커밋을 1번 라인에 있는 커밋과 합친다는 의미다 (리베이스 액션에 대한 자세한 설명은 하단의 주석을 참고)&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;1 pick d323105 [TASK-A] A 작업함&lt;br /&gt;2 fixup da964a1 [TASK-A] A 작업 추가함&lt;br /&gt;3 pick 758713d [TASK-B] B 작업함&lt;br /&gt;4&lt;br /&gt;5 # Rebase 23427f8..da964a1 onto 23427f8 (3 commands)&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 수정하고 저장하고 편집기를 닫으면, 1, 2번 라인의 변경내용을 합쳐 커밋을 다시 생성하는데 사용할 커밋메세지 입력을 위해 에디터가 다시 열린다. 저장하고 닫으면 커밋이 3개에서 2개로 변경된다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;* 1d31ae4 [TASK-A] A 작업함 (HEAD -&amp;gt; main)&lt;br /&gt;* ebbc74a [TASK-B] B 작업함&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;6. 브랜치 간의 변경사항을 보고 싶어요&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;main 브랜치를 운영서버에 배포하고 develop 브랜치를 개발서버에 배포하는 구조라고 하자. 오늘이 배포하는 날이다. 어떤 사항을 배포하는지 확인하고 싶을 경우가 있다. 커밋 단위로 말이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 지금 운영중인 main 브랜치에 비해 오늘까지 개발한 develop 브랜치의 변경사항을 커밋별로 보고 싶을 때는 아래 명령어를 사용하자.&lt;/p&gt;
&lt;pre id=&quot;code_1738758497839&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ git log main..develop&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기준이 되는 브랜치(여기서는 main)를 앞에 먼저 입력하고 `..` 뒤에 비교할 브랜치(여기서는 develop)를 입력한다. 이렇게 나온 커밋 목록으로 main 브랜치 대비 develop 브랜치에 추가한 변경내용을 파악할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;7. 원격 저장소와 연결하고 싶어요&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;깃헙 같은 원격에 있는 저장소를 컴퓨터에 다운로드 하는 것을 &lt;b&gt;복제(clone)&lt;/b&gt;한다 라고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원격 저장소는 다운로드를 위한 주소를 제공하는데 git으로 시작되는 주소나 https로 시작하는 주소를 제공한다. ssh 방식이고 공개키가 서버에 등록되어 있다면 이 방식으로 다운로드 할 수 있다. 후자는 아이디와 비밀번호를 사용해서 다운로드 할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보통 깃헙을 원격저장소로 많이 사용하는데 공개키를 등록해서 ssh 방식으로 사용하는 편이다.&lt;/p&gt;
&lt;pre id=&quot;code_1738758643222&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ git clone {원격 저장소 주소}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다운로드한 원격 저장소는 저장소 이름으로 로컬에 폴더를 생성한다. 여기서 작업을 하고 커밋을 만든 뒤 원격으로 내용을 업로드 하는 것을 &quot;푸시(push)&quot;라고 한다.&lt;/p&gt;
&lt;pre id=&quot;code_1738758680195&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ git push origin HEAD&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;협업하다보면 원격저장소를 클론한 다른 사용자가 코드를 먼저 푸시했을 수도 있다. 이럴땐 저장소의 최신버전을 가져와야 하는데 이것을 &lt;b&gt;패치(fetch)&lt;/b&gt;라고 한다.&lt;/p&gt;
&lt;pre id=&quot;code_1738758714825&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ git fetch&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;패치하면 원격 저장소의 최신 업데이트 내용을 로컬에 가져올 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가져온 변경사항을 현재 브랜치와 머지하려면 `pull` 명령어를 사용한다.&lt;/p&gt;
&lt;pre id=&quot;code_1738758745301&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ git pull origin master&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원격 저장소의 변경 내용을 가져와 로컬 저장소에 반영된다. 패스트 포워드가 가능하면 바로 반영하고 그렇지 않으면 머지 커밋을 추가로 만든다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내가 작업한 내용을 깨끗하게 유지하고 싶으면 머지 커밋을 만들지 않고 리베이스로 변경사항을 반영할 수도 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1738758793818&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ git pull origin master --rebase&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 하면 원격저장소에 있는 변경사항을 먼저 쌓고 그 위에 내가 작업한 변경사항을 쌓는 방식이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 머지보다 리베이스를 선호하는 편이다. 커밋 그래프를 좀 더 단순하게 유지하고 싶어서 그렇다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;8. 원격 저장소를 여러개 관리하고 싶어요&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원격 저장소로부터 클론하면 원격지 일므은 기본적으로 &quot;origin&quot;이다. `remote` 원격지를 관리하는 명령어인데 `-v` 옵션으로 원격저장소 목록을 볼 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1738758869803&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ git remote -v&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원격 저장소는 여러개 붙일 수 있다. 원격 저장소가 여러개 있어야 할 이유는 뭘까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;깃헙 포크를 이용하면 이게 무척 유용하다. 깃헙의 포크는 타인의 계정에 있는 저장소를 내 계정의 저장소로 하나 가져오는 기능이다. 내 계정으로 포크한 저장소를 클론하면 기본 이름인 origin으로 가져온다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 타인의 원격 저장소에 변경사항이 있는데 이걸 내 로컬에 가져오고 싶으면 어떻게 할까? 이때 &quot;원격 저장소 하나를 더 추가&quot;할 수 있다. 보통은 upstream이란 이름으로 원격저장소 하나를 더 추가한다.&lt;/p&gt;
&lt;pre id=&quot;code_1738758959212&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ git remote add upstream {원격저장소주소}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 하면 하나의 저장소에 두 개의 원격지를 연결할 수 있다. origin으로 내 원격 저장소에 코드를 푸시하다가, 원본 저장소의 변경사항을 받을때는 upstream을 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원격 저장소의 주소를 변경하고 싶을때는 `set-url`로 변경할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1738759007151&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ git remote set-url {변경된 원격저장소 주소}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론 원격 저장소의 이름을 변경할 수도 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1738759029969&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ git remote -m {저장소 이름} {저장소 이름 신규}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;정리&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가끔 프로젝트를 맡게되면 기존 코드를 훑어보고 커밋 로그를 들여다 본다. 어떤 코드는 커밋 단위가 명확해서 코드를 변경한 의도가 쉽게 이해된다. 한편 정보가 부족한 커밋 메세지는 코드 변경 내용만 보고 파악해야 하는데 이게 쉽지 않은 일이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히 코드리뷰를 요청받게 되면 커밋 작성법에 대한 아쉬움이 많이 남는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;A 기능 구현&quot; 이라고 메세지를 기록한 커밋을 들여다보면 구현한 코드의 양이 무척 많다. 그 코드에는 기능 구현을 위한 작업들이 통째로 들어가 있는 경우가 대부분이다. 에디터가 컨벤션 규칙에 따라 자동으로 수정한 변경 내용이 포함된 경우도 있다. 기능 구현과는 아무런 관계가 없는 코드인데도 말이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 코드리뷰는 사실 잘 안하게 된다. 깃 사용 방법을 조금이라도 더 알았더라면.. 그리고 조금만 더 꼼꼼하다면 이라는 아쉬움이 남는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드 뿐만 아니라 글도 깃을 활용하면 좋겠다는 생각을 한다. 물론 워드파일처럼 어플리케이션만의 인코딩 처리의 저장 방식을 따르는 파일을 변경사항까지 추적하는건 한계다. 만약 마크다운으로 글을 쓴다면 깃으로 관리하는 것이 무척 편하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://jeonghwan-kim.github.io/dev/2020/02/10/git-usage.html#%ED%97%A4%EB%93%9C&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://jeonghwan-kim.github.io/dev/2020/02/10/git-usage.html#%ED%97%A4%EB%93%9C&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1738416383765&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;깃(Git) 개념과 상황별 팁&quot; data-og-description=&quot;git-usage 저장소가 어느새 스타 10&amp;hellip;&quot; data-og-host=&quot;jeonghwan-kim.github.io&quot; data-og-source-url=&quot;https://jeonghwan-kim.github.io/dev/2020/02/10/git-usage.html#%ED%97%A4%EB%93%9C&quot; data-og-url=&quot;https://jeonghwan-kim.github.io/dev/2020/02/10/git-usage.html&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/fgamF/hyX7UAHyLU/QLn9hi7VHocxMREnUSYMc1/img.jpg?width=200&amp;amp;height=200&amp;amp;face=0_0_200_200,https://scrap.kakaocdn.net/dn/C9ZUS/hyX7WSTmnd/muxSIzSvsJNcufRV3atHek/img.jpg?width=726&amp;amp;height=667&amp;amp;face=0_0_726_667,https://scrap.kakaocdn.net/dn/vtILa/hyX70OxmUS/pyAKSLHTwFnx7IwxiB57gk/img.jpg?width=726&amp;amp;height=662&amp;amp;face=0_0_726_662&quot;&gt;&lt;a href=&quot;https://jeonghwan-kim.github.io/dev/2020/02/10/git-usage.html#%ED%97%A4%EB%93%9C&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://jeonghwan-kim.github.io/dev/2020/02/10/git-usage.html#%ED%97%A4%EB%93%9C&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/fgamF/hyX7UAHyLU/QLn9hi7VHocxMREnUSYMc1/img.jpg?width=200&amp;amp;height=200&amp;amp;face=0_0_200_200,https://scrap.kakaocdn.net/dn/C9ZUS/hyX7WSTmnd/muxSIzSvsJNcufRV3atHek/img.jpg?width=726&amp;amp;height=667&amp;amp;face=0_0_726_667,https://scrap.kakaocdn.net/dn/vtILa/hyX70OxmUS/pyAKSLHTwFnx7IwxiB57gk/img.jpg?width=726&amp;amp;height=662&amp;amp;face=0_0_726_662');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;깃(Git) 개념과 상황별 팁&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;git-usage 저장소가 어느새 스타 10&amp;hellip;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;jeonghwan-kim.github.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>STUDY/etc</category>
      <category>GIT</category>
      <category>github</category>
      <author>宋白手</author>
      <guid isPermaLink="true">https://ooo-k.tistory.com/461</guid>
      <comments>https://ooo-k.tistory.com/461#entry461comment</comments>
      <pubDate>Sun, 2 Feb 2025 00:18:33 +0900</pubDate>
    </item>
    <item>
      <title>Web Components : Custom Elements</title>
      <link>https://ooo-k.tistory.com/460</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;기본 설명&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Custom Elements는 사용자 HTML Element를 만들게 해준다. 그리고 이는 DOM의 모든 기능을 다 사용할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본적으로 두 가지 타입으로 생성한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;표준 HTML 요소를 상속하지 않은 Elements. 요소는 상속하지 않지만 HTML Element는 상속 한다.&lt;/li&gt;
&lt;li&gt;표준 HTML 요소를 상속한 Element.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 생성한 Element는 Lifecycle callback을 class 안에 정의하여 특정 시점에 동작 하도록 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;기본 사용법&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;독립적인 사용자 정의 요소&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1737958592484&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class MyComponent extends HTMLElement {
  constructor() {
    // 항상 super를 호출 해야 한다.
    super();
    
    this.innerHTML = `&amp;lt;h1&amp;gt;This is my Element&amp;lt;/h1&amp;gt;`;
  }
}

customElements.define(&quot;my-component&quot;, MyComponent);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;customElements.define에서 정의할 때 아래 사항을 꼭 유념해야 한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;Name for the new custom element. Note that custom element names must contain a `hypen`.&lt;br /&gt;새 커스텀 엘리먼트의 이름입니다. 커스텀 요소 이름에는 `하이픈`이 포함되어야 합니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;constructor 메서드 안에 `this`는 customElements를 가리킨다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;`&amp;lt;my-element&amp;gt;`를 사용해 보면 `&amp;lt;h1&amp;gt;` element가 생성 되고 `This is My Element`가 표현 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;Built-in 사용자 정의 요소&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 상속할 Element를 extends하여 class를 정의 한다.&lt;/p&gt;
&lt;pre id=&quot;code_1737958958468&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class ButtonComponent extends HTMLInputElement {
  constructor() {
    super();
    
    this.style.border = '1px solid';
    this.addEventListener('click', (e) =&amp;gt; e.preventDefault());
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정의한 사용자 요소를 등록하빈다. 이때 상속한 Element를 인수로 넘겨 준다.&lt;/p&gt;
&lt;pre id=&quot;code_1737959036088&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;customElements.define(&quot;button-component&quot;, ButtonComponent, {
  extends: &quot;button&quot;,
});&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마지막으로 `&amp;lt;button&amp;gt;` 사용 시 `is` attribute에 `my-button`을 사용자 요소로 사용함을 알려 준다.&lt;/p&gt;
&lt;pre id=&quot;code_1737959092016&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;button is='button-component'&amp;gt;Click&amp;lt;/button&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;생명 주기 콜백&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;custom component가 생성되고 삭제 되기 까지 네 가지 상태에 따른 별도의 callback을 정의할 수 있습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;connectedCallback&lt;/b&gt;: 사용자 정의 요소가 문서에 연결된 요소에 추가될 때마다 호출됩니다. 이것은 노드가 이동 될 때마다 발생할 것이며, 요소의 내용이 완전히 해석되기 전에 발생할 지도 모릅니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;disconnectedCallback&lt;/b&gt;: 사용자 정의 요소가 document DOM에서 연결 해제 되었을 때마다 호출됩니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;adoptedCallback&lt;/b&gt;: 사용자 정의 요소가 새로운 document로 이동 되었을 때마다 호출됩니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;attributeChangedCallback&lt;/b&gt;: 사용자 정의 요소의 특성들 중 하나가 추가되거나, 제거되거나, 변경될 때마다 호출됩니다. 어떤 특성이 변경에 대해 알릴지는 static get `observedAttributes` 메서드에서 명시됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 생명 주기 콜백을 보면 vue, react 등에서 사용했던 `componentDidMount`, 'mounted'와 비슷한 모양입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용법도 아래와 같이 비슷합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1737959508083&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;connectedCallback() {
  console.log('연결 완료');
}
disconnectedCallback() {
  console.log('연결 해제 완료');
}
adoptedCallback() {
  console.log('Element가 다른 page로 이동 하였습니다.');
}
attributeChangedCallback(name, oldValue, newValue) {
  console.log('name이 변경 되었습니다.');
}

static get observedAttributes() {
  // 변경을 관찰하고자 하는 attribute를 나열한다.
  // 아래 반환값들이 변경되면 attributeChangedCallback 이 호출된다.
  return ['autoFocus', 'disabled', 'form', 'value'];
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;Web Components 사용하기&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어서 `&amp;lt;custom-input&amp;gt;` 이라고 입력하면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;`&amp;lt;label&amp;gt;&amp;lt;input&amp;gt;` 이렇게 2개의 태그가 안에 출현하게 만들고 싶다면 아래와 같이 사용하면 된다.&lt;/p&gt;
&lt;pre id=&quot;code_1737960199144&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class InputComponent extends HTMLElement {
  connectedCallback() {
    this.innerHTML = `&amp;lt;label&amp;gt;이름을 입력하세요.&amp;lt;/label&amp;gt;&amp;lt;input&amp;gt;`;
  }
}
customElements.define('input-component', InputComponent);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1737960215239&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;script type=&quot;module&quot; src=&quot;components/input-component.js&quot; defer&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;input-component&amp;gt;&amp;lt;/input-component&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;HTML 태그를 innerHTML보다 효율적으로 짜고 싶다면&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1737960389894&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class InputComponent extends HTMLElement {
  connectedCallback() {
    let label = document.createElement('label');
    this.appendChild(label);
    
    this.innerHTML = `&amp;lt;label&amp;gt;이름을 입력해주세요.&amp;lt;/label&amp;gt;&amp;lt;input&amp;gt;`
  }
}
customElements.define('input-component', InputComponent);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;위와 방식으로 사용하면 `innerHTML`보다 html 생성 속도가 10배 빨라진다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;파라미터 문법 구현 가능&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1737960513549&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class InputComponent extends HTMLElement {
  connectedCallback() {
    let name = this.getAttribute('name');
    this.innerHTML = `&amp;lt;label&amp;gt;${name} 인풋입니다.&amp;lt;/label&amp;gt;&amp;lt;input&amp;gt;`;
  }
}
customElements.define('input-component', InputComponent);&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1737960542445&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;input-component name='비밀번호'&amp;gt;&amp;lt;/input-component&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;attribute 변경 감지하기&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;attribute가 바뀌면, html도 자동으로 업데이트 해줄 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;name이라는 custom attribute가 변경될 때마다, 특정 코드를 실행할 수도 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1737960769433&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class InputComponent extends HTMLElement {
  connectedCallback() {
    let name = this.getAttribute('name');
    this.innerHTML = `&amp;lt;label&amp;gt;${name}을 입력하세요.&amp;lt;/label&amp;gt;&amp;lt;input&amp;gt;`;
  }
  
  static get observedAttributes() {
    return ['name'];
  }
  
  attributeChangedCallback() {
    // attribute 변경 시 실행할 코드
    this.innerHTML = `&amp;lt;label&amp;gt;${name}이 변경되었습니다.&amp;lt;/label&amp;gt;&amp;lt;input&amp;gt;`;
  }
}
customElements.define('input-component', InputComponent);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;사용예시&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1737675751544&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&quot;en&quot;&amp;gt;
&amp;lt;head&amp;gt;
  &amp;lt;meta charset=&quot;UTF-8&quot;&amp;gt;
  &amp;lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&amp;gt;
  &amp;lt;title&amp;gt;Web Component&amp;lt;/title&amp;gt;
  &amp;lt;script type=&quot;module&quot; src=&quot;components/header-component.js&quot; defer&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
  &amp;lt;!-- 헤더 컴포넌트 --&amp;gt;
  &amp;lt;header-component&amp;gt;&amp;lt;/header-component&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;components/header-component.js&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1737675772251&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class HeaderComponent extends HTMLElement {
  connectedCallback() {
    this.innerHTML = `
      &amp;lt;header&amp;gt;
        &amp;lt;nav&amp;gt;
          &amp;lt;a href=&quot;#&quot; id=&quot;home-link&quot;&amp;gt;Home&amp;lt;/a&amp;gt;
          &amp;lt;a href=&quot;#&quot; id=&quot;about-link&quot;&amp;gt;About&amp;lt;/a&amp;gt;
          &amp;lt;a href=&quot;/contact&quot;&amp;gt;Contact&amp;lt;/a&amp;gt;
        &amp;lt;/nav&amp;gt;
      &amp;lt;/header&amp;gt;
    `;

    this.addEventListener('click', (e) =&amp;gt; {
      e.preventDefault();
      console.log('click');
    });
  }
}
customElements.define('header-component', HeaderComponent);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://velog.io/@gil0127/Web-Components-%EC%BB%A4%EC%8A%A4%ED%85%80-HTML-%ED%83%9C%EA%B7%B8-%EB%A7%8C%EB%93%A4%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://velog.io/@gil0127/Web-Components-%EC%BB%A4%EC%8A%A4%ED%85%80-HTML-%ED%83%9C%EA%B7%B8-%EB%A7%8C%EB%93%A4%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1737675646730&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Web Components : 커스텀 HTML 태그 만들기&quot; data-og-description=&quot;HTML 태그 덩어리들도 자주 쓰이는 것들은 모아서 함수처럼 저장해둘 수 있다. 그리고 필요할 때마다 조금씩 변경해서 쓸 수있는데, 이것을 Web Components라고 한다.&quot; data-og-host=&quot;velog.io&quot; data-og-source-url=&quot;https://velog.io/@gil0127/Web-Components-%EC%BB%A4%EC%8A%A4%ED%85%80-HTML-%ED%83%9C%EA%B7%B8-%EB%A7%8C%EB%93%A4%EA%B8%B0&quot; data-og-url=&quot;https://velog.io/@gil0127/Web-Components-커스텀-HTML-태그-만들기&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/3nAVm/hyX7RJkDRg/xGzyWIvVJ5IeXvz9UYdFz1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/IMhPN/hyX70GgBoj/SVPmEPrHJfLO5BHSxuBFTk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/bfis0N/hyX4lFjWBn/9zWMwyKOOKqb8SYVeDKHrK/img.png?width=1464&amp;amp;height=795&amp;amp;face=0_0_1464_795&quot;&gt;&lt;a href=&quot;https://velog.io/@gil0127/Web-Components-%EC%BB%A4%EC%8A%A4%ED%85%80-HTML-%ED%83%9C%EA%B7%B8-%EB%A7%8C%EB%93%A4%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://velog.io/@gil0127/Web-Components-%EC%BB%A4%EC%8A%A4%ED%85%80-HTML-%ED%83%9C%EA%B7%B8-%EB%A7%8C%EB%93%A4%EA%B8%B0&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/3nAVm/hyX7RJkDRg/xGzyWIvVJ5IeXvz9UYdFz1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/IMhPN/hyX70GgBoj/SVPmEPrHJfLO5BHSxuBFTk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/bfis0N/hyX4lFjWBn/9zWMwyKOOKqb8SYVeDKHrK/img.png?width=1464&amp;amp;height=795&amp;amp;face=0_0_1464_795');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Web Components : 커스텀 HTML 태그 만들기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;HTML 태그 덩어리들도 자주 쓰이는 것들은 모아서 함수처럼 저장해둘 수 있다. 그리고 필요할 때마다 조금씩 변경해서 쓸 수있는데, 이것을 Web Components라고 한다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;velog.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://velog.io/@rageboom/Custom-Elements&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://velog.io/@rageboom/Custom-Elements&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1737679648897&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[웹 컴포넌트] Custom Elements&quot; data-og-description=&quot;Custom Elements는 사용자 HTML Element를 만들게 해준다. 그리고 이는 DOM의 모든 기능을 다 사용 할 수 있다.기본적으로 두 가지 타입으로 생성한다.표준 HTML 요소를 상속하지 않은 Element. 요소는 상속하&quot; data-og-host=&quot;velog.io&quot; data-og-source-url=&quot;https://velog.io/@rageboom/Custom-Elements&quot; data-og-url=&quot;https://velog.io/@rageboom/Custom-Elements&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/50rWL/hyX7QwTkZ8/Br7cp5XgQF2qM7Tcz76150/img.png?width=950&amp;amp;height=500&amp;amp;face=0_0_950_500&quot;&gt;&lt;a href=&quot;https://velog.io/@rageboom/Custom-Elements&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://velog.io/@rageboom/Custom-Elements&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/50rWL/hyX7QwTkZ8/Br7cp5XgQF2qM7Tcz76150/img.png?width=950&amp;amp;height=500&amp;amp;face=0_0_950_500');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[웹 컴포넌트] Custom Elements&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Custom Elements는 사용자 HTML Element를 만들게 해준다. 그리고 이는 DOM의 모든 기능을 다 사용 할 수 있다.기본적으로 두 가지 타입으로 생성한다.표준 HTML 요소를 상속하지 않은 Element. 요소는 상속하&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;velog.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/ko/docs/Web/API/Window/customElements&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://developer.mozilla.org/ko/docs/Web/API/Window/customElements&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1737961236434&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Window.customElements - Web API | MDN&quot; data-og-description=&quot;Window 인터페이스의 customElements 읽기 전용 속성은 새로운 사용자 지정 요소를 등록하거나, 이전에 등록한 요소의 정보를 받아올 수 있는 CustomElementRegistry 객체의 참조를 반환합니다.&quot; data-og-host=&quot;developer.mozilla.org&quot; data-og-source-url=&quot;https://developer.mozilla.org/ko/docs/Web/API/Window/customElements&quot; data-og-url=&quot;https://developer.mozilla.org/ko/docs/Web/API/Window/customElements&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bGJIt6/hyX7YPBumT/jaUtOwzWvlMzLGNsSiLu7k/img.png?width=1920&amp;amp;height=1080&amp;amp;face=0_0_1920_1080&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/ko/docs/Web/API/Window/customElements&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://developer.mozilla.org/ko/docs/Web/API/Window/customElements&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bGJIt6/hyX7YPBumT/jaUtOwzWvlMzLGNsSiLu7k/img.png?width=1920&amp;amp;height=1080&amp;amp;face=0_0_1920_1080');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Window.customElements - Web API | MDN&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Window 인터페이스의 customElements 읽기 전용 속성은 새로운 사용자 지정 요소를 등록하거나, 이전에 등록한 요소의 정보를 받아올 수 있는 CustomElementRegistry 객체의 참조를 반환합니다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;developer.mozilla.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Web_components&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://developer.mozilla.org/en-US/docs/Web/API/Web_components&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1737961254496&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Web Components - Web APIs | MDN&quot; data-og-description=&quot;Web Components is a suite of different technologies allowing you to create reusable custom elements &amp;mdash; with their functionality encapsulated away from the rest of your code &amp;mdash; and utilize them in your web apps.&quot; data-og-host=&quot;developer.mozilla.org&quot; data-og-source-url=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Web_components&quot; data-og-url=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Web_components&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/srziZ/hyX7VL68nt/gK34e8XKsYZloWN6fjktyk/img.png?width=1920&amp;amp;height=1080&amp;amp;face=0_0_1920_1080&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Web_components&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Web_components&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/srziZ/hyX7VL68nt/gK34e8XKsYZloWN6fjktyk/img.png?width=1920&amp;amp;height=1080&amp;amp;face=0_0_1920_1080');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Web Components - Web APIs | MDN&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Web Components is a suite of different technologies allowing you to create reusable custom elements &amp;mdash; with their functionality encapsulated away from the rest of your code &amp;mdash; and utilize them in your web apps.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;developer.mozilla.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/ko/docs/Web/API/Web_components&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://developer.mozilla.org/ko/docs/Web/API/Web_components&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1737961305709&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;웹 컴포넌트 - Web API | MDN&quot; data-og-description=&quot;웹 컴포넌트는 그 기능을 나머지 코드로부터 캡슐화하여 재사용 가능한 커스텀 엘리먼트를 생성하고 웹 앱에서 활용할 수 있도록 해주는 다양한 기술들의 모음입니다.&quot; data-og-host=&quot;developer.mozilla.org&quot; data-og-source-url=&quot;https://developer.mozilla.org/ko/docs/Web/API/Web_components&quot; data-og-url=&quot;https://developer.mozilla.org/ko/docs/Web/API/Web_components&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dOzHw6/hyX4q1juit/rR9eioVNzz6kNNe5kNlUHK/img.png?width=1920&amp;amp;height=1080&amp;amp;face=0_0_1920_1080&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/ko/docs/Web/API/Web_components&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://developer.mozilla.org/ko/docs/Web/API/Web_components&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dOzHw6/hyX4q1juit/rR9eioVNzz6kNNe5kNlUHK/img.png?width=1920&amp;amp;height=1080&amp;amp;face=0_0_1920_1080');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;웹 컴포넌트 - Web API | MDN&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;웹 컴포넌트는 그 기능을 나머지 코드로부터 캡슐화하여 재사용 가능한 커스텀 엘리먼트를 생성하고 웹 앱에서 활용할 수 있도록 해주는 다양한 기술들의 모음입니다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;developer.mozilla.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>STUDY/JavaScript</category>
      <category>customelement</category>
      <category>WebComponents</category>
      <author>宋白手</author>
      <guid isPermaLink="true">https://ooo-k.tistory.com/460</guid>
      <comments>https://ooo-k.tistory.com/460#entry460comment</comments>
      <pubDate>Fri, 24 Jan 2025 08:43:10 +0900</pubDate>
    </item>
    <item>
      <title>svg see: SVG 파일 미리보기 extention</title>
      <link>https://ooo-k.tistory.com/459</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;svg 미리 보기 활성화 하는 방법&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파일을 직접 열지 않아도 미리 볼 수 있기 때문에, 작업 속도가 빨라집니다. 특히 여러 SVG 파일을 다루는 경우 시간 절약 효과가 더욱 뛰어납니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;확장 프로그램 설치 하기&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/tibold/svg-explorer-extension/releases&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/tibold/svg-explorer-extension/releases&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SVG SEE 프로그래 설치 사이트로 이동해서 컴퓨터 사양에 맞는 버전을 다운로드 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(32bit -&amp;gt; x86, 64bit -&amp;gt; x64)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1818&quot; data-origin-height=&quot;554&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SbsOw/btsL25mJ64Z/IEkapIXqjcDj76nl6sUC8k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SbsOw/btsL25mJ64Z/IEkapIXqjcDj76nl6sUC8k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SbsOw/btsL25mJ64Z/IEkapIXqjcDj76nl6sUC8k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSbsOw%2FbtsL25mJ64Z%2FIEkapIXqjcDj76nl6sUC8k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1818&quot; height=&quot;554&quot; data-origin-width=&quot;1818&quot; data-origin-height=&quot;554&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://mu08.tistory.com/198&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://mu08.tistory.com/198&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1732497816481&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[윈도우 팁]SVG 파일, 이제 미리보기로 확인해보자(svg see)&quot; data-og-description=&quot;안녕하세요 무택입니다 :) 오늘은 아주 간단하게 SVG 미리 보기 활성화하는 방법에 대해 포스팅해 보도록 하겠습니다! 웹 디자인 작업 시, SVG 이미지는 벡터 그래픽의 장점을 살려 다양한 용도로 &quot; data-og-host=&quot;mu08.tistory.com&quot; data-og-source-url=&quot;https://mu08.tistory.com/198&quot; data-og-url=&quot;https://mu08.tistory.com/198&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/J7IQA/hyXDbWC19F/b5r9OtyfobiNGi7eNiCrEK/img.gif?width=640&amp;amp;height=320&amp;amp;face=0_0_640_320,https://scrap.kakaocdn.net/dn/diapj8/hyXzTQAjAy/c95Fnv2OP8cryIjbB0vFsk/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/SrObB/hyXDboOiDv/3ckj38vTQJvr1cHKKhkgk1/img.gif?width=640&amp;amp;height=320&amp;amp;face=0_0_640_320&quot;&gt;&lt;a href=&quot;https://mu08.tistory.com/198&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://mu08.tistory.com/198&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/J7IQA/hyXDbWC19F/b5r9OtyfobiNGi7eNiCrEK/img.gif?width=640&amp;amp;height=320&amp;amp;face=0_0_640_320,https://scrap.kakaocdn.net/dn/diapj8/hyXzTQAjAy/c95Fnv2OP8cryIjbB0vFsk/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/SrObB/hyXDboOiDv/3ckj38vTQJvr1cHKKhkgk1/img.gif?width=640&amp;amp;height=320&amp;amp;face=0_0_640_320');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[윈도우 팁]SVG 파일, 이제 미리보기로 확인해보자(svg see)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;안녕하세요 무택입니다 :) 오늘은 아주 간단하게 SVG 미리 보기 활성화하는 방법에 대해 포스팅해 보도록 하겠습니다! 웹 디자인 작업 시, SVG 이미지는 벡터 그래픽의 장점을 살려 다양한 용도로&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;mu08.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/tibold/svg-explorer-extension/releases&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/tibold/svg-explorer-extension/releases&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1732497835761&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;Releases &amp;middot; tibold/svg-explorer-extension&quot; data-og-description=&quot;Extension module for Windows Explorer to render SVG thumbnails, so that you can have an overview of your SVG files - tibold/svg-explorer-extension&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/tibold/svg-explorer-extension/releases&quot; data-og-url=&quot;https://github.com/tibold/svg-explorer-extension/releases&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/b0XYQw/hyXC95yE4e/xnoVgmyzqq1PXIkJTwQde1/img.png?width=1200&amp;amp;height=600&amp;amp;face=961_129_1079_258,https://scrap.kakaocdn.net/dn/xGzrE/hyXDelv2Dv/eb4WzRmxf6mQNp3VCewyWK/img.png?width=1200&amp;amp;height=600&amp;amp;face=961_129_1079_258&quot;&gt;&lt;a href=&quot;https://github.com/tibold/svg-explorer-extension/releases&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/tibold/svg-explorer-extension/releases&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/b0XYQw/hyXC95yE4e/xnoVgmyzqq1PXIkJTwQde1/img.png?width=1200&amp;amp;height=600&amp;amp;face=961_129_1079_258,https://scrap.kakaocdn.net/dn/xGzrE/hyXDelv2Dv/eb4WzRmxf6mQNp3VCewyWK/img.png?width=1200&amp;amp;height=600&amp;amp;face=961_129_1079_258');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Releases &amp;middot; tibold/svg-explorer-extension&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Extension module for Windows Explorer to render SVG thumbnails, so that you can have an overview of your SVG files - tibold/svg-explorer-extension&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>STUDY/etc</category>
      <category>extention</category>
      <category>SVG</category>
      <category>svg see</category>
      <author>宋白手</author>
      <guid isPermaLink="true">https://ooo-k.tistory.com/459</guid>
      <comments>https://ooo-k.tistory.com/459#entry459comment</comments>
      <pubDate>Mon, 25 Nov 2024 10:24:18 +0900</pubDate>
    </item>
    <item>
      <title>맥북 (Mac OS) M2 톰캣 설치하기</title>
      <link>https://ooo-k.tistory.com/458</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. 톰캣 설치&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아파치 톰캣 사이트에 접속합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://tomcat.apache.org/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://tomcat.apache.org/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;716&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/RhUsf/btsJprftC4v/ijF3irydR15BgsWydr14n1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/RhUsf/btsJprftC4v/ijF3irydR15BgsWydr14n1/img.png&quot; data-alt=&quot;https://velog.io/@wijoonwu&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/RhUsf/btsJprftC4v/ijF3irydR15BgsWydr14n1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRhUsf%2FbtsJprftC4v%2FijF3irydR15BgsWydr14n1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;716&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;716&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://velog.io/@wijoonwu&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;페이지 왼쪽의 `Download` 카테고리에서 다운로드 할 톰캣 버전을 클릭합니다.&lt;/li&gt;
&lt;li&gt;내게 맞는 톰캣 버전을 찾는 방법 참고: &lt;a href=&quot;https://itworldyo.tistory.com/88&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://itworldyo.tistory.com/88&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;668&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bcRKMe/btsJortYBhW/gBPkk1y0j9hGqcMlnN5Rr1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bcRKMe/btsJortYBhW/gBPkk1y0j9hGqcMlnN5Rr1/img.png&quot; data-alt=&quot;https://velog.io/@wijoonwu&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bcRKMe/btsJortYBhW/gBPkk1y0j9hGqcMlnN5Rr1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbcRKMe%2FbtsJortYBhW%2FgBPkk1y0j9hGqcMlnN5Rr1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;668&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;668&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://velog.io/@wijoonwu&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;`Binary Distributions` 항목에서 `tar.gz` 파일을 클릭 해 다운로드 합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;800&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Znslk/btsJpgrMIc4/ZyCrqXriDBtIYrKnjGZog0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Znslk/btsJpgrMIc4/ZyCrqXriDBtIYrKnjGZog0/img.png&quot; data-alt=&quot;https://velog.io/@wijoonwu&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Znslk/btsJpgrMIc4/ZyCrqXriDBtIYrKnjGZog0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZnslk%2FbtsJpgrMIc4%2FZyCrqXriDBtIYrKnjGZog0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;800&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;800&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://velog.io/@wijoonwu&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;저장 경로를 설정하고 `저장` 버튼을 클릭합니다.&lt;/li&gt;
&lt;li&gt;다운로드가 시작됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;888&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dh8bNw/btsJpob1VBS/kvjiTRBvCdQVehZd23TPLk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dh8bNw/btsJpob1VBS/kvjiTRBvCdQVehZd23TPLk/img.png&quot; data-alt=&quot;https://velog.io/@wijoonwu&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dh8bNw/btsJpob1VBS/kvjiTRBvCdQVehZd23TPLk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdh8bNw%2FbtsJpob1VBS%2FkvjiTRBvCdQVehZd23TPLk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;888&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;888&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://velog.io/@wijoonwu&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;888&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/PVxRZ/btsJqeGv2R5/vbJbXL8clRm7w766O7t2Ck/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/PVxRZ/btsJqeGv2R5/vbJbXL8clRm7w766O7t2Ck/img.png&quot; data-alt=&quot;https://velog.io/@wijoonwu&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/PVxRZ/btsJqeGv2R5/vbJbXL8clRm7w766O7t2Ck/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPVxRZ%2FbtsJqeGv2R5%2FvbJbXL8clRm7w766O7t2Ck%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;888&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;888&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://velog.io/@wijoonwu&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;설치 된 `tar.gz` 파일을 더블 클릭하여 압축을 해제 합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. 톰캣 실행&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;503&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/IEVr5/btsJqgdfy5h/lgsL4fkjcL5f1edGWoOoHK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/IEVr5/btsJqgdfy5h/lgsL4fkjcL5f1edGWoOoHK/img.png&quot; data-alt=&quot;https://velog.io/@wijoonwu&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/IEVr5/btsJqgdfy5h/lgsL4fkjcL5f1edGWoOoHK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIEVr5%2FbtsJqgdfy5h%2FlgsL4fkjcL5f1edGWoOoHK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;503&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;503&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://velog.io/@wijoonwu&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;503&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cIfCp8/btsJqks89h2/5tQtvSy6Gi9CmRWN0CROj1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cIfCp8/btsJqks89h2/5tQtvSy6Gi9CmRWN0CROj1/img.png&quot; data-alt=&quot;https://velog.io/@wijoonwu&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cIfCp8/btsJqks89h2/5tQtvSy6Gi9CmRWN0CROj1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcIfCp8%2FbtsJqks89h2%2F5tQtvSy6Gi9CmRWN0CROj1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;503&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;503&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://velog.io/@wijoonwu&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;`Finder`에서 톰캣이 설치된 경로로 접속합니다.&lt;/li&gt;
&lt;li&gt;키보드에서 `command` + `option` + `c` 를 동시에 눌러 경로를 복사합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;906&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CVHO3/btsJpe8yDRy/I7hkFLfuWoEUrUou61KGW1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CVHO3/btsJpe8yDRy/I7hkFLfuWoEUrUou61KGW1/img.png&quot; data-alt=&quot;https://velog.io/@wijoonwu&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CVHO3/btsJpe8yDRy/I7hkFLfuWoEUrUou61KGW1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCVHO3%2FbtsJpe8yDRy%2FI7hkFLfuWoEUrUou61KGW1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;906&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;906&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://velog.io/@wijoonwu&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;터미널을 실행합니다.&lt;/li&gt;
&lt;li&gt;`cd` + 복사해둔 경로 + `/bin` 명령어를 입력합니다.&lt;/li&gt;
&lt;li&gt;`./startup.sh` 명령어를 입력하여 톰캣을 실행합니다.&lt;/li&gt;
&lt;li&gt;`Tomcat started.` 문구가 출력되면 성공입니다.&lt;/li&gt;
&lt;li&gt;`./shutdown.sh` 명령어를 입력하면 톰캣 서버가 중지됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;800&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oKUkt/btsJoq2Zfat/3cpujw0QWsiXD22FJLU1uK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oKUkt/btsJoq2Zfat/3cpujw0QWsiXD22FJLU1uK/img.png&quot; data-alt=&quot;https://velog.io/@wijoonwu&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oKUkt/btsJoq2Zfat/3cpujw0QWsiXD22FJLU1uK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoKUkt%2FbtsJoq2Zfat%2F3cpujw0QWsiXD22FJLU1uK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;800&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;800&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://velog.io/@wijoonwu&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;인터넷 브라우저를 실행한 뒤 주소창에 `localhost:8080` 을 입력합니다.&lt;/li&gt;
&lt;li&gt;위 이미지와 같이 톰캣 페이지가 출력되면 성공입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;참고:)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://velog.io/@wijoonwu/%EB%A7%A5%EB%B6%81Mac-OS-M1-%ED%86%B0%EC%BA%A3-%EC%84%A4%EC%B9%98%ED%95%98%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://velog.io/@wijoonwu/%EB%A7%A5%EB%B6%81Mac-OS-M1-%ED%86%B0%EC%BA%A3-%EC%84%A4%EC%B9%98%ED%95%98%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1725343214532&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;맥북(Mac OS) M1 톰캣 설치하기&quot; data-og-description=&quot;맥북(Mac OS) M1 환경에서 톰캣 서버를 구현해봅니다.&quot; data-og-host=&quot;velog.io&quot; data-og-source-url=&quot;https://velog.io/@wijoonwu/%EB%A7%A5%EB%B6%81Mac-OS-M1-%ED%86%B0%EC%BA%A3-%EC%84%A4%EC%B9%98%ED%95%98%EA%B8%B0&quot; data-og-url=&quot;https://velog.io/@wijoonwu/맥북Mac-OS-M1-톰캣-설치하기&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bp8X9J/hyWY71cD5p/MfiqXBQEnzQRbnPrAp4pm0/img.png?width=2802&amp;amp;height=1568&amp;amp;face=0_0_2802_1568,https://scrap.kakaocdn.net/dn/caBSeK/hyWV1heLHS/oLtBlRLxioRHHg8oWcBh91/img.png?width=2802&amp;amp;height=1568&amp;amp;face=0_0_2802_1568,https://scrap.kakaocdn.net/dn/UXEop/hyWZld4Tbe/KbpRwaabFUvDRXNTg1cuJ0/img.png?width=2802&amp;amp;height=1568&amp;amp;face=0_0_2802_1568&quot;&gt;&lt;a href=&quot;https://velog.io/@wijoonwu/%EB%A7%A5%EB%B6%81Mac-OS-M1-%ED%86%B0%EC%BA%A3-%EC%84%A4%EC%B9%98%ED%95%98%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://velog.io/@wijoonwu/%EB%A7%A5%EB%B6%81Mac-OS-M1-%ED%86%B0%EC%BA%A3-%EC%84%A4%EC%B9%98%ED%95%98%EA%B8%B0&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bp8X9J/hyWY71cD5p/MfiqXBQEnzQRbnPrAp4pm0/img.png?width=2802&amp;amp;height=1568&amp;amp;face=0_0_2802_1568,https://scrap.kakaocdn.net/dn/caBSeK/hyWV1heLHS/oLtBlRLxioRHHg8oWcBh91/img.png?width=2802&amp;amp;height=1568&amp;amp;face=0_0_2802_1568,https://scrap.kakaocdn.net/dn/UXEop/hyWZld4Tbe/KbpRwaabFUvDRXNTg1cuJ0/img.png?width=2802&amp;amp;height=1568&amp;amp;face=0_0_2802_1568');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;맥북(Mac OS) M1 톰캣 설치하기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;맥북(Mac OS) M1 환경에서 톰캣 서버를 구현해봅니다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;velog.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>STUDY/etc</category>
      <category>Apache</category>
      <category>tomcat</category>
      <author>宋白手</author>
      <guid isPermaLink="true">https://ooo-k.tistory.com/458</guid>
      <comments>https://ooo-k.tistory.com/458#entry458comment</comments>
      <pubDate>Tue, 3 Sep 2024 15:02:22 +0900</pubDate>
    </item>
    <item>
      <title>디자인 시스템 만들기: breakpoint</title>
      <link>https://ooo-k.tistory.com/457</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;들어가며&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;디자인을 할 때 여러 해상도를 대응해야 하는 것은 필수적이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히나 요즘에는 너무나도 다양한 기기들이 나오다 보니 하나의 서비스를 만들 때 모바일 앱이 아닌 이상 데스크탑, 태블릿, 모바일 그리고 이 디바이스에서도 다양한 해상도를 대응해야 한다. (갤럭시 플립, 폴더&amp;middot;&amp;middot;&amp;middot;)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 디자인 시스템 Foundation 영역에 들어갈 브레이크 포인트를 설정하는 데 있어서도 많은 고민과 리서치가 필요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;1. 글로벌 기업의 디자인 시스템 리서치&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Google의 Meterial 디자인 시스템, MUI 디자인 시스템 그리고 기타 브랜드의 디자인 시스템을 찾아 공통적인 영역을 도출&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Google Meterial Design System&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;Breakpoint Range&lt;br /&gt;(dp)&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;Portrait&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;Landscape&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;Window&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;Colums&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;Margines / Gutters*&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;0 ~ 359&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;small handset&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;xsmall&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;4&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;16&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;360 ~ 399&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;medium handset&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;xsmall&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;4&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;16&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;400 ~ 479&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;large handset&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;xsmall&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;4&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;16&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;480 ~ 599&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;large handset&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;small handset&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;xsmall&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;4&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;16&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;600 ~ 719&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;small tablet&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;medium handset&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;small&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;8&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;16&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;720 ~ 839&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;large tablet&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;large handset&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;small&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;8&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;16&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;840 ~ 959&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;large tablet&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;large handset&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;small&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;12&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;24&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;960 ~ 1023&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;small tablet&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;small&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;12&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;24&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;1024 ~ 1279&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;large tablet&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;medium&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;12&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;24&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;1280 ~ 1439&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;large tablet&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;medium&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;12&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;24&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;1440 ~ 1599&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;large&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;12&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;24&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;1600 ~ 1919&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;large&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;12&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;24&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;1920 +&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;xlarge&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;12&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;24&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;MUI Design System&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Define breakpoint&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Each breakpoint (a key) matches with a fixed screen width (a value):&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;xs&lt;/b&gt;: extra-small: 0px&lt;/li&gt;
&lt;li&gt;&lt;b&gt;sm&lt;/b&gt;, small: 600px&lt;/li&gt;
&lt;li&gt;&lt;b&gt;md&lt;/b&gt;, medium: 900px&lt;/li&gt;
&lt;li&gt;&lt;b&gt;lg&lt;/b&gt;, large: 1200px&lt;/li&gt;
&lt;li&gt;&lt;b&gt;xl&lt;/b&gt;, extra-large: 1536px&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Carbon Design System&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 14.2857%;&quot;&gt;Breakpoint&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%;&quot;&gt;Value (px/rem)&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%;&quot;&gt;Columns&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%;&quot;&gt;Size (%)&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%;&quot;&gt;Size&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%;&quot;&gt;Padding&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%;&quot;&gt;Margin&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 14.2857%;&quot;&gt;Small&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%;&quot;&gt;320 / 20&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%;&quot;&gt;4&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%;&quot;&gt;25%&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%;&quot;&gt;80px&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%;&quot;&gt;16px&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%;&quot;&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 14.2857%;&quot;&gt;Medium&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%;&quot;&gt;672 / 42&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%;&quot;&gt;8&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%;&quot;&gt;12.5%&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%;&quot;&gt;80px&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%;&quot;&gt;16px&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%;&quot;&gt;16px&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 14.2857%;&quot;&gt;Large&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%;&quot;&gt;1056 / 66&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%;&quot;&gt;16&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%;&quot;&gt;6.25%&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%;&quot;&gt;64px&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%;&quot;&gt;16px&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%;&quot;&gt;16px&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 14.2857%;&quot;&gt;X-Large&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%;&quot;&gt;1312 / 82&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%;&quot;&gt;16&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%;&quot;&gt;6.25%&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%;&quot;&gt;80px&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%;&quot;&gt;16px&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%;&quot;&gt;16px&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 14.2857%;&quot;&gt;Max&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%;&quot;&gt;1584 / 99&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%;&quot;&gt;16&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%;&quot;&gt;6.25%&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%;&quot;&gt;96px&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%;&quot;&gt;16px&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%;&quot;&gt;24px&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구글 머터리얼 디자인 시스템을 보면 굉장히 다양한 해상도를 대응하는것을 볼 수 있다. 총 13개로 브레이크 포인트를 나누고 5~6가지로 기기를 구별하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MUI 같은 경우에는 총 4가지 브레이크 포인트를 나누었고 Carbon은 5개로 나누었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 세 가지에서 공통적인 부분은 &lt;b&gt;모바일 사이즈는 600px 이하로 잡았다는 것&lt;/b&gt;이고, 나머지 부분들은 각자의 서비스에 맞춰서 나누어 값들이 다양했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;넓은 범위로서 공통점은 700px, 1200px, 1600px 이하 영역에서 브레이크 포인트를 잡았다는 점이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;2. 가장 많이 사용하는 해상도 찾기&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://gs.statcounter.com/screen-resolution-stats#monthly-202401-202501-bar&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://gs.statcounter.com/screen-resolution-stats#monthly-202401-202501-bar&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1737962811964&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Screen Resolution Stats Worldwide | Statcounter Global Stats&quot; data-og-description=&quot;This graph shows the stats of screen resolutions worldwide based on over 5 billion monthly page views.&quot; data-og-host=&quot;gs.statcounter.com&quot; data-og-source-url=&quot;https://gs.statcounter.com/screen-resolution-stats#monthly-202401-202501-bar&quot; data-og-url=&quot;https://gs.statcounter.com/screen-resolution-stats&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cpejjj/hyX4w8ioe4/ouHn0dZmKzFYk6cFOFuIBk/img.png?width=1200&amp;amp;height=576&amp;amp;face=0_0_1200_576,https://scrap.kakaocdn.net/dn/NE2Gx/hyX74oLebQ/heTeB8aWj4tgpW6806HLh0/img.png?width=1200&amp;amp;height=576&amp;amp;face=0_0_1200_576&quot;&gt;&lt;a href=&quot;https://gs.statcounter.com/screen-resolution-stats#monthly-202401-202501-bar&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://gs.statcounter.com/screen-resolution-stats#monthly-202401-202501-bar&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cpejjj/hyX4w8ioe4/ouHn0dZmKzFYk6cFOFuIBk/img.png?width=1200&amp;amp;height=576&amp;amp;face=0_0_1200_576,https://scrap.kakaocdn.net/dn/NE2Gx/hyX74oLebQ/heTeB8aWj4tgpW6806HLh0/img.png?width=1200&amp;amp;height=576&amp;amp;face=0_0_1200_576');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Screen Resolution Stats Worldwide | Statcounter Global Stats&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;This graph shows the stats of screen resolutions worldwide based on over 5 billion monthly page views.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;gs.statcounter.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Desktop&lt;/b&gt;: 1920x1080, 1366x768, 1536x864&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Tablet&lt;/b&gt;: 768x1024, 810x1080, 820x1180&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Mobile&lt;/b&gt;: 360x800, 390x844, 393x873&lt;/li&gt;
&lt;/ul&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style4&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;Mobile&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;0 ~ 599px&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;Small Tablet&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;600px ~ 1023px&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;Large Tablet&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;1024px ~ 1439px&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;Desktop&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;1440px ~ 1920&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 표가 정답은 아니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;많은 리서치와 데이터를 바탕으로 브레이크 포인트를 서비스에 맞게 설정해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://brunch.co.kr/@bommade/22&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://brunch.co.kr/@bommade/22&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1720756910652&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;디자인 시스템 만들기-3 브레이크포인트&quot; data-og-description=&quot;Foundation - Breakpoint(브레이크 포인트) 정하기 | 들어가며 디자인을 할 때 여러 해상도를 대응해야 하는 것은 필수적이다. 특히나 요즘에는 너무나도 다양한 기기들이 나오다 보니 하나의 서비스를&quot; data-og-host=&quot;brunch.co.kr&quot; data-og-source-url=&quot;https://brunch.co.kr/@bommade/22&quot; data-og-url=&quot;https://brunch.co.kr/@bommade/22&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bFTt8t/hyWzEFnzF3/kC14vvXhGeOcpIvdVkkBGK/img.png?width=1280&amp;amp;height=456&amp;amp;face=0_0_1280_456,https://scrap.kakaocdn.net/dn/bip7tb/hyWzrTzxtM/SsgCKvwvNrADjiLa6hg1q0/img.png?width=500&amp;amp;height=500&amp;amp;face=0_0_500_500,https://scrap.kakaocdn.net/dn/SQCGY/hyWzDT0ptl/tbicMMakNKdSpgJRW4mI0K/img.png?width=1280&amp;amp;height=1657&amp;amp;face=0_0_1280_1657&quot;&gt;&lt;a href=&quot;https://brunch.co.kr/@bommade/22&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://brunch.co.kr/@bommade/22&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bFTt8t/hyWzEFnzF3/kC14vvXhGeOcpIvdVkkBGK/img.png?width=1280&amp;amp;height=456&amp;amp;face=0_0_1280_456,https://scrap.kakaocdn.net/dn/bip7tb/hyWzrTzxtM/SsgCKvwvNrADjiLa6hg1q0/img.png?width=500&amp;amp;height=500&amp;amp;face=0_0_500_500,https://scrap.kakaocdn.net/dn/SQCGY/hyWzDT0ptl/tbicMMakNKdSpgJRW4mI0K/img.png?width=1280&amp;amp;height=1657&amp;amp;face=0_0_1280_1657');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;디자인 시스템 만들기-3 브레이크포인트&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Foundation - Breakpoint(브레이크 포인트) 정하기 | 들어가며 디자인을 할 때 여러 해상도를 대응해야 하는 것은 필수적이다. 특히나 요즘에는 너무나도 다양한 기기들이 나오다 보니 하나의 서비스를&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;brunch.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>STUDY/etc</category>
      <category>breakpoint</category>
      <category>Designsystem</category>
      <author>宋白手</author>
      <guid isPermaLink="true">https://ooo-k.tistory.com/457</guid>
      <comments>https://ooo-k.tistory.com/457#entry457comment</comments>
      <pubDate>Fri, 12 Jul 2024 13:01:55 +0900</pubDate>
    </item>
    <item>
      <title>[Git] 맥 vscode 터미널에 git 현재 branch 표시하기</title>
      <link>https://ooo-k.tistory.com/456</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;vscode 터미널에 git 현재 branch 표시하기&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;vscode 터미널 사용 시 현재 브랜치 명이 표시되지 않아 불편하다.&lt;/p&gt;
&lt;pre id=&quot;code_1720177102241&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ touch .bash_profile
$ open .bash_profile&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;터미널에 .bash_profile 파일을 만들어주고 열어준다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1720177122381&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;parse_git_branch() {
  git branch 2&amp;gt; /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/ (\1)/'
}
export PS1=&quot;\u@\h \W\[\033[32m\]\$(parse_git_branch)\[\033[00m\] $ &quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;이 코드를 그대로 저장 후&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1720177136856&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ source .bash_profile&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;방금 그 파일을 실행시켜준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://velog.io/@kcy8507/Git-%EB%A7%A5-vscode-%ED%84%B0%EB%AF%B8%EB%84%90%EC%97%90-git-%ED%98%84%EC%9E%AC-branch-%ED%91%9C%EC%8B%9C%ED%95%98%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://velog.io/@kcy8507/Git-%EB%A7%A5-vscode-%ED%84%B0%EB%AF%B8%EB%84%90%EC%97%90-git-%ED%98%84%EC%9E%AC-branch-%ED%91%9C%EC%8B%9C%ED%95%98%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1737963482060&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[Git] 맥 vscode 터미널에 git 현재 branch 표시하기&quot; data-og-description=&quot;터미널에 현재 브랜치 표시가 안돼서 지금 내가 어느 브랜치로 푸시를 하는건지 자꾸 확인해줘야했다. 터미널에 .bash_profile 파일을 만들어주고 열어준다.이 코드를 그대로 저장 후 방금 그 파일&quot; data-og-host=&quot;velog.io&quot; data-og-source-url=&quot;https://velog.io/@kcy8507/Git-%EB%A7%A5-vscode-%ED%84%B0%EB%AF%B8%EB%84%90%EC%97%90-git-%ED%98%84%EC%9E%AC-branch-%ED%91%9C%EC%8B%9C%ED%95%98%EA%B8%B0&quot; data-og-url=&quot;https://velog.io/@kcy8507/Git-맥-vscode-터미널에-git-현재-branch-표시하기&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/Dm1WC/hyX7XpDq6Y/CKwm42bfxCLf1j3UKnfbA0/img.png?width=1280&amp;amp;height=45&amp;amp;face=0_0_1280_45,https://scrap.kakaocdn.net/dn/bvECzK/hyX4AplQBt/aaMaik07u8NdGocYSgMcoK/img.png?width=1280&amp;amp;height=45&amp;amp;face=0_0_1280_45,https://scrap.kakaocdn.net/dn/cWtbNp/hyX72dn3Mp/qrjOrUghkkYG4HXPukqffK/img.png?width=421&amp;amp;height=421&amp;amp;face=0_0_421_421&quot;&gt;&lt;a href=&quot;https://velog.io/@kcy8507/Git-%EB%A7%A5-vscode-%ED%84%B0%EB%AF%B8%EB%84%90%EC%97%90-git-%ED%98%84%EC%9E%AC-branch-%ED%91%9C%EC%8B%9C%ED%95%98%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://velog.io/@kcy8507/Git-%EB%A7%A5-vscode-%ED%84%B0%EB%AF%B8%EB%84%90%EC%97%90-git-%ED%98%84%EC%9E%AC-branch-%ED%91%9C%EC%8B%9C%ED%95%98%EA%B8%B0&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/Dm1WC/hyX7XpDq6Y/CKwm42bfxCLf1j3UKnfbA0/img.png?width=1280&amp;amp;height=45&amp;amp;face=0_0_1280_45,https://scrap.kakaocdn.net/dn/bvECzK/hyX4AplQBt/aaMaik07u8NdGocYSgMcoK/img.png?width=1280&amp;amp;height=45&amp;amp;face=0_0_1280_45,https://scrap.kakaocdn.net/dn/cWtbNp/hyX72dn3Mp/qrjOrUghkkYG4HXPukqffK/img.png?width=421&amp;amp;height=421&amp;amp;face=0_0_421_421');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[Git] 맥 vscode 터미널에 git 현재 branch 표시하기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;터미널에 현재 브랜치 표시가 안돼서 지금 내가 어느 브랜치로 푸시를 하는건지 자꾸 확인해줘야했다. 터미널에 .bash_profile 파일을 만들어주고 열어준다.이 코드를 그대로 저장 후 방금 그 파일&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;velog.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>STUDY/etc</category>
      <category>Branch</category>
      <category>Terminal</category>
      <category>vscode</category>
      <author>宋白手</author>
      <guid isPermaLink="true">https://ooo-k.tistory.com/456</guid>
      <comments>https://ooo-k.tistory.com/456#entry456comment</comments>
      <pubDate>Fri, 5 Jul 2024 19:59:10 +0900</pubDate>
    </item>
    <item>
      <title>javascript scroll event 제어</title>
      <link>https://ooo-k.tistory.com/454</link>
      <description>&lt;blockquote data-ke-style=&quot;style2&quot;&gt;스크롤 기능을 막아야 하는 상황에서 대부분은 body 에 `overflow-y: hidden` 을 주는 방법이 제시되지만, 그렇지 않은 경우 자바스크립트로 이를 처리해야 한다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;javascript로 `scroll`, `mousewheel`, `touchmove` 등의 이벤트를 걸어 `e.preventDefulat()`로 이벤트를 막아볼 수 있겠지만, `mousewheel` 이벤트와 같이 스크롤과 관련 된 이벤트는 기본적으로 `passive`로 처리되어 있어 추가 옵션을 설정 할 수 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;&lt;b&gt;아래와 같은 오류 발생&lt;/b&gt;&lt;/i&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1737964405940&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[Intervention] Unable to preventDefault inside passive event listener due to target being treated as passive. See &amp;lt;URL&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;`wheel` 이벤트를 사용하여 스크롤을 감지하고 `preventDefault`를 호출하면서 성능 최적화와 문제해결을 동시에 할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;`passive` 옵션을 추가하고, `wheel` 이벤트로 바꾸면 body 스크롤링이 잘 멈춘다.&lt;/p&gt;
&lt;pre id=&quot;code_1719966661040&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function wheelevent(e) {
    e.preventDefault();
}
document.querySelector(&quot;body&quot;).addEventListener('wheel', wheelevent, { passive: false });
document.querySelector(&quot;body&quot;).removeEventListener('wheel', wheelevent, { passive: false });&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;`wheel` 이벤트와 `scroll`, `mousewheel` 의 차이, 그리고 성능 최적화에 대한 내용&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;`wheel` 이벤트는 마우스 휠 또는 트랙패드 등 더 다양한 입력 장치에서 발생하는 스크롤 이벤트로, `mousewheel` 이벤트와 비슷하지만, `wheel` 이벤트가 표준에 더 가깝고 여러 입력 장치에서의 일관성을 제공한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또 `wheel` 이벤트가 `passive`로 처리되는 것은 브라우저가 성능 최적화를 위해 도입한 개념 중 하나이고, 브라우저는 기본적으로 `wheel` 이벤트에 대해 `passive` 플래그를 설정하기 때문에 이벤트 리스너 내에서 `preventDefault`를 호출하지 못하게 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;`passive` 플래그가 설정된 이벤트 리스너에서 `preventDefault`를 호출하는 것은 브라우저가 스크롤링 동작을 최적화하기 위해 이벤트 핸들러를 비동기적응로 실행하도록 허용하게 된ㄴ데, 이로 인해 호출 순서가 보장되지 않기 때문에 스크롤을 막아야 하는 경우에는 `passive: false`로 설정 된 이벤트 리스너를 사용해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://velog.io/@h_jinny/javascript-body-%EC%8A%A4%ED%81%AC%EB%A1%A4-%EB%A7%89%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://velog.io/@h_jinny/javascript-body-%EC%8A%A4%ED%81%AC%EB%A1%A4-%EB%A7%89%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1737963816226&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[javascript] body 스크롤 막기&quot; data-og-description=&quot;스크롤 기능을 막아야하는 상황에서 대부분은 body 에 overflow-y: hidden 을 주는 방법이 제시되지만, 그렇지 않은 경우 자바스크립트로 이를 처리해야한다.처음엔 아래와 같이 이벤트를 주었지만 작&quot; data-og-host=&quot;velog.io&quot; data-og-source-url=&quot;https://velog.io/@h_jinny/javascript-body-%EC%8A%A4%ED%81%AC%EB%A1%A4-%EB%A7%89%EA%B8%B0&quot; data-og-url=&quot;https://velog.io/@h_jinny/javascript-body-스크롤-막기&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/jHtG3/hyX4pVCjzO/s7DnjU2TTyEdNdFaNIMA50/img.png?width=1418&amp;amp;height=182&amp;amp;face=0_0_1418_182,https://scrap.kakaocdn.net/dn/hyKRo/hyX4wga26c/h069yU19qgxU81ZyGKR6bk/img.png?width=1418&amp;amp;height=182&amp;amp;face=0_0_1418_182,https://scrap.kakaocdn.net/dn/qivbg/hyX4tqbA22/LC5xe0kJREsOtC5f4NdBkK/img.jpg?width=2048&amp;amp;height=2048&amp;amp;face=755_710_1244_1241&quot;&gt;&lt;a href=&quot;https://velog.io/@h_jinny/javascript-body-%EC%8A%A4%ED%81%AC%EB%A1%A4-%EB%A7%89%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://velog.io/@h_jinny/javascript-body-%EC%8A%A4%ED%81%AC%EB%A1%A4-%EB%A7%89%EA%B8%B0&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/jHtG3/hyX4pVCjzO/s7DnjU2TTyEdNdFaNIMA50/img.png?width=1418&amp;amp;height=182&amp;amp;face=0_0_1418_182,https://scrap.kakaocdn.net/dn/hyKRo/hyX4wga26c/h069yU19qgxU81ZyGKR6bk/img.png?width=1418&amp;amp;height=182&amp;amp;face=0_0_1418_182,https://scrap.kakaocdn.net/dn/qivbg/hyX4tqbA22/LC5xe0kJREsOtC5f4NdBkK/img.jpg?width=2048&amp;amp;height=2048&amp;amp;face=755_710_1244_1241');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[javascript] body 스크롤 막기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;스크롤 기능을 막아야하는 상황에서 대부분은 body 에 overflow-y: hidden 을 주는 방법이 제시되지만, 그렇지 않은 경우 자바스크립트로 이를 처리해야한다.처음엔 아래와 같이 이벤트를 주었지만 작&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;velog.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://solbel.tistory.com/1299&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://solbel.tistory.com/1299&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1737963816209&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[javascript/jquery] [Intervention] Unable to preventDefault inside passive event listener due to target being treated as passive&quot; data-og-description=&quot;[javascript/jquery] [Intervention] Unable to preventDefault inside passive event listener due to target being treated as passive. See 해결 방법 반응협 웹에서 스크롤이라든가 드래그라든가 액션이 일어날때 반응하기 위해서 w&quot; data-og-host=&quot;solbel.tistory.com&quot; data-og-source-url=&quot;https://solbel.tistory.com/1299&quot; data-og-url=&quot;https://solbel.tistory.com/1299&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/v9hTV/hyX4n4yNrT/3B2BrawsCnv2xTEZwE73C1/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/bKLSAP/hyX4tKvEWL/PClciXNSzUOwh87LfbzhpK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/b04Qsn/hyX4qNNn2M/TO92LJpOtL3KokMdBEKoCk/img.jpg?width=500&amp;amp;height=500&amp;amp;face=0_0_500_500&quot;&gt;&lt;a href=&quot;https://solbel.tistory.com/1299&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://solbel.tistory.com/1299&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/v9hTV/hyX4n4yNrT/3B2BrawsCnv2xTEZwE73C1/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/bKLSAP/hyX4tKvEWL/PClciXNSzUOwh87LfbzhpK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/b04Qsn/hyX4qNNn2M/TO92LJpOtL3KokMdBEKoCk/img.jpg?width=500&amp;amp;height=500&amp;amp;face=0_0_500_500');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[javascript/jquery] [Intervention] Unable to preventDefault inside passive event listener due to target being treated as passive&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;[javascript/jquery] [Intervention] Unable to preventDefault inside passive event listener due to target being treated as passive. See 해결 방법 반응협 웹에서 스크롤이라든가 드래그라든가 액션이 일어날때 반응하기 위해서 w&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;solbel.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>STUDY/JavaScript</category>
      <category>body</category>
      <category>passive</category>
      <category>scroll</category>
      <author>宋白手</author>
      <guid isPermaLink="true">https://ooo-k.tistory.com/454</guid>
      <comments>https://ooo-k.tistory.com/454#entry454comment</comments>
      <pubDate>Wed, 3 Jul 2024 09:31:09 +0900</pubDate>
    </item>
    <item>
      <title>프론트엔드 성능 최적화</title>
      <link>https://ooo-k.tistory.com/453</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;브라우저 동작 원리&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;브라우저 로딩 과정: 파싱 &amp;gt; 스타일 &amp;gt; 레이아웃(리플로우) &amp;gt; 페인트 &amp;gt; 합성 &amp;amp; 렌더&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프론트엔드의 성능 최적화를 확인하기에 앞서 브라우저가 어떻게 화면을 사용자에게 보여주는지를 알아야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://velog.io/@kmlee95/%EB%B8%8C%EB%9D%BC%EC%9A%B0%EC%A0%80%EC%9D%98-%EB%8F%99%EC%9E%91%EA%B3%BC%EC%A0%95%EB%B6%80%ED%84%B0-React&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://velog.io/@kmlee95/%EB%B8%8C%EB%9D%BC%EC%9A%B0%EC%A0%80%EC%9D%98-%EB%8F%99%EC%9E%91%EA%B3%BC%EC%A0%95%EB%B6%80%ED%84%B0-React&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;프론트엔드 성능 최적화&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;프론트 엔드 성능 최적화에는 `웹 페이지 로드 최적화`, `웹 페이지 렌더링 최적화`가 있다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;1. 웹 페이지 로드 최적화&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;(1) 브라우저 상에서 최적화&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;`DOMContentLoaded': html, css 파싱이 끝난 시점&lt;/li&gt;
&lt;li&gt;`Loaded`: html 상에 모든 리소스가 load 된 시점&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;크롬 개발자 도구&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;375&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/GEMrC/btsL1yQWpH0/FPPI4iMmruiPTdga9ZHPD1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/GEMrC/btsL1yQWpH0/FPPI4iMmruiPTdga9ZHPD1/img.png&quot; data-alt=&quot;https://velog.io/@kmlee95/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EC%84%B1%EB%8A%A5%EC%B5%9C%EC%A0%81%ED%99%94&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/GEMrC/btsL1yQWpH0/FPPI4iMmruiPTdga9ZHPD1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGEMrC%2FbtsL1yQWpH0%2FFPPI4iMmruiPTdga9ZHPD1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;693&quot; height=&quot;325&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;375&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://velog.io/@kmlee95/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EC%84%B1%EB%8A%A5%EC%B5%9C%EC%A0%81%ED%99%94&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;html, css 파싱을 진행하다가 script 태그와 만나게 되면 javascript 파싱을 진행하게 되고, 그 이후로 동기적으로 파싱이 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 html, css를 파싱하면서 자바스크립트로 인해 `block resource`가 발생하는걸 방지해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1737965591817&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;!-- block resource 방지 --&amp;gt;
&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;meta charset=&quot;utf-8&quot;&amp;gt;
    &amp;lt;title&amp;gt;My Test Page&amp;lt;/title&amp;gt;
    &amp;lt;!-- css 위치 --&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;div&amp;gt;&amp;lt;/div&amp;gt;
    
    &amp;lt;!-- js 위치 --&amp;gt;
    &amp;lt;script&amp;gt;
      // ...
    &amp;lt;/script&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;(2) 리소스 용량 최적화&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리소스 용량을 줄임으로써 리소스 다운로드 시간을 최적화 할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;크롬 개발자 도구의 network 탭 -&amp;gt; 필터에서 리소스 유형&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;984&quot; data-origin-height=&quot;252&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sMup6/btsL2AN0P7w/AtWp5IAy1PbZRuhOFXKHE1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sMup6/btsL2AN0P7w/AtWp5IAy1PbZRuhOFXKHE1/img.png&quot; data-alt=&quot;https://velog.io/@kmlee95/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EC%84%B1%EB%8A%A5%EC%B5%9C%EC%A0%81%ED%99%94&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sMup6/btsL2AN0P7w/AtWp5IAy1PbZRuhOFXKHE1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsMup6%2FbtsL2AN0P7w%2FAtWp5IAy1PbZRuhOFXKHE1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;543&quot; height=&quot;139&quot; data-origin-width=&quot;984&quot; data-origin-height=&quot;252&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://velog.io/@kmlee95/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EC%84%B1%EB%8A%A5%EC%B5%9C%EC%A0%81%ED%99%94&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;불필요한 코드는 제거한다.&lt;/li&gt;
&lt;li&gt;압축 및 난독화로 용량을 최소화 한다.&lt;/li&gt;
&lt;li&gt;간결한 셀렉터를 사용한다.&lt;/li&gt;
&lt;li&gt;모듈번들러(webpack) css, js 번들링 한다.&lt;/li&gt;
&lt;li&gt;캐싱할 필요 없는 style은 내부 스타일 시트를 사용한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;2. 웹 페이지 렌더링 최적화&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;페이지 렌더링 최적화의 목표는 `레이아웃을 최대한 빠르게`, `최대한 적게 발생시키는 것`&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;웹 페이지를 렌더링 하기 위해서는 DOM, CSS가 필요하다. 그러나 다양한 기능과 효과를 구현하기 위해서는 자바스크립트를 많이 사용한다. 자바스크립트는 브라우저에서 단일 스레드로 동작하기 때문에 자바스크립트의 실행 시간은 곧 렌더링 성능과 직결된다. 결국엔 자바스크립트에서 실행되는 코드가 최적화 될 수 있게 구성해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;3. 레이아웃 최적화&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;렌더링 과정에서 `레이아웃은 DOM 요소들이 화면에 어느 위치에서 어떤 크기로 배치될지`를 결정하게 되는 계산 과정이다. 레이아웃은 글자의 크기를 일일히 계산하고 요소 간 관계를 모두 파악해야 하는 과정이므로 시간이 오래 걸린다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;92&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/blNKDX/btsL3fCFYwx/38hvh0H5KNobCUFJX3Yiz0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/blNKDX/btsL3fCFYwx/38hvh0H5KNobCUFJX3Yiz0/img.jpg&quot; data-alt=&quot;https://velog.io/@kmlee95/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EC%84%B1%EB%8A%A5%EC%B5%9C%EC%A0%81%ED%99%94&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/blNKDX/btsL3fCFYwx/38hvh0H5KNobCUFJX3Yiz0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FblNKDX%2FbtsL3fCFYwx%2F38hvh0H5KNobCUFJX3Yiz0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;92&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;92&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://velog.io/@kmlee95/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EC%84%B1%EB%8A%A5%EC%B5%9C%EC%A0%81%ED%99%94&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;레이아웃 최적화의 목표는 자바스크립트 실행 과정과 렌더링이 다시 일어나는 과정에서 레이아웃에 걸리는 시간을 단축하고 최대한 발생시키지 않도록 하는 것이다. 아래 세 가지를 확인한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;(1) 자바스크립트 실행 최적화&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바스크립트 실행 시간이 긴 경우, 한 프레임 처리가 오래걸려 렌더링 성능이 떨어진다. 많은 작업을 수행할 때 자바스크립트 실행 시간은 오래걸린다. 그래서 자바스크립트가 DOM 및 스타일 변경에 어떤 영향을 끼치는지 확인하고, 수정해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;문제1: 강제 동기 레이아웃 피하기&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1737966152055&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 계산된 값을 반환하기 전에 변경된 스타일이 계산 결과에 적용되어 있지 않으면 변경 이전 값을 반환하기 때문에 브라우저는 동기로 레이아웃을 해야만 한다.

const tabBtn = document.getElementById(&quot;tab_btn&quot;);

tabBtn.style.fontSize = &quot;24px&quot;;
console.log(testBlock.offsetTop);  // offsetTop 호출 직전 브라우저 내부에서는 동기 레이아웃이 발생한다.
tabBtn.style.margin = &quot;10px&quot;;
// 레이아웃&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;문제2: 레이아웃 스래싱 피하기&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1737966322623&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 한 프레임 내에서 강제 동기 레이아웃이 연속적으로 발생하면 성능이 더욱 저하된다.
function resizeAllParagraphs() {
  const box = document.getElementById(&quot;box&quot;);
  const paragraphs = document.querySelectorAll(&quot;.paragraphs&quot;);
  
  for (let i=0; i&amp;lt;paragraphs.length; i++) {
    paragraphs[i].style.width = box.offsetWidth + &quot;px&quot;;
  }
}

// 레이아웃 스래싱을 개선한 코드
function resizeAllParagraphs() {
  const box = document.getElementById(&quot;box&quot;);
  const paragraphs = document.querySelectorAll(&quot;.paragraphs&quot;);
  const width = box.offsetWidth;
  
  for (let i=0; i&amp;lt;paragraphs.length; i++) {
    paragraphs[i].style.width = width + &quot;px&quot;;
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;(2) HTML, CSS 최적화&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;화면을 렌더링하기 위해서 필요한 데이터는 HTLM과 CSS로, 각각 DOM 트리와 CSSOM 트리를 만들고 렌더링할 때 사용된다. DOM 트리와 CSSOM 트리를 변경하면 렌더링을 유발하고 트리가 클 수록 더 많은 계산이 필요하다. 그러므로 HTML과 CSS를 최적화하여 렌더링 성능을 향상시킬 수 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;css가 복잡하고 많을수록 스타일 계산과 레이아웃이 오래 걸린다. 복잡한 선택자는 시간이 많이 걸리므로 피한다.&lt;/li&gt;
&lt;li&gt;dom이 작고 깊이가 얕을수록 계산이 빠르므로 불필요한 래퍼 엘리먼트는 제거한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;(3) 애니메이션 최적화&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;한 프레임 처리가 16ms(60fps)&lt;/b&gt; 내로 완료되어야 렌더링 시 끊기는 현상 없이 자연스러운 렌더링을 만들어낼 수 있다. 애니메이션을 구현할 때 네이티브 자바스크립트 API를 사용하는 것보다 CSS 사용을 권장한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://velog.io/@kmlee95/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EC%84%B1%EB%8A%A5%EC%B5%9C%EC%A0%81%ED%99%94&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://velog.io/@kmlee95/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EC%84%B1%EB%8A%A5%EC%B5%9C%EC%A0%81%ED%99%94&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1719537839356&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;프론트엔드 성능최적화&quot; data-og-description=&quot;프론트엔드 성능 최적화에 관해 알아보자.&quot; data-og-host=&quot;velog.io&quot; data-og-source-url=&quot;https://velog.io/@kmlee95/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EC%84%B1%EB%8A%A5%EC%B5%9C%EC%A0%81%ED%99%94&quot; data-og-url=&quot;https://velog.io/@kmlee95/프론트엔드-성능최적화&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/gVuyW/hyWrYK6Rxw/obdkx08Hjfx35zvHEy0gyk/img.png?width=700&amp;amp;height=350&amp;amp;face=0_0_700_350,https://scrap.kakaocdn.net/dn/kYOcE/hyWrRSMsLM/UokOVElDR48UKcsF6cslX0/img.png?width=700&amp;amp;height=350&amp;amp;face=0_0_700_350,https://scrap.kakaocdn.net/dn/csX3Jb/hyWrPm6fRV/i7qLkL7bX3wHixbRnPZ6F0/img.png?width=800&amp;amp;height=375&amp;amp;face=0_0_800_375&quot;&gt;&lt;a href=&quot;https://velog.io/@kmlee95/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EC%84%B1%EB%8A%A5%EC%B5%9C%EC%A0%81%ED%99%94&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://velog.io/@kmlee95/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EC%84%B1%EB%8A%A5%EC%B5%9C%EC%A0%81%ED%99%94&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/gVuyW/hyWrYK6Rxw/obdkx08Hjfx35zvHEy0gyk/img.png?width=700&amp;amp;height=350&amp;amp;face=0_0_700_350,https://scrap.kakaocdn.net/dn/kYOcE/hyWrRSMsLM/UokOVElDR48UKcsF6cslX0/img.png?width=700&amp;amp;height=350&amp;amp;face=0_0_700_350,https://scrap.kakaocdn.net/dn/csX3Jb/hyWrPm6fRV/i7qLkL7bX3wHixbRnPZ6F0/img.png?width=800&amp;amp;height=375&amp;amp;face=0_0_800_375');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;프론트엔드 성능최적화&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;프론트엔드 성능 최적화에 관해 알아보자.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;velog.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://coffeeandcakeandnewjeong.tistory.com/34&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://coffeeandcakeandnewjeong.tistory.com/34&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1737966508745&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[프론트엔드] 성능 최적화 정리&quot; data-og-description=&quot;목차 0. 개요 1. 브라우저 동작 원리 2. 성능 최적화 2.1 페이지 로드 최적화 2.2 페이지 렌더링 최적화 3. 성능 측정 기준 3.1 브라우저 내부 이벤트 기준 3.2 사용자 기준 성능 지표 3.3 사용자 기준 성&quot; data-og-host=&quot;coffeeandcakeandnewjeong.tistory.com&quot; data-og-source-url=&quot;https://coffeeandcakeandnewjeong.tistory.com/34&quot; data-og-url=&quot;https://coffeeandcakeandnewjeong.tistory.com/34&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/jeyF8/hyX7PrBfFI/J3OX6i9cvH4LkfUR92sPW1/img.png?width=280&amp;amp;height=280&amp;amp;face=0_0_280_280,https://scrap.kakaocdn.net/dn/bp2IYy/hyX7THxscQ/ksRnlCKbBsFOPLdfILMmqk/img.png?width=280&amp;amp;height=280&amp;amp;face=0_0_280_280,https://scrap.kakaocdn.net/dn/brCnH6/hyX4sEOMxg/DwacTweKJCwkDtAKJpr1QK/img.png?width=3029&amp;amp;height=475&amp;amp;face=0_0_3029_475&quot;&gt;&lt;a href=&quot;https://coffeeandcakeandnewjeong.tistory.com/34&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://coffeeandcakeandnewjeong.tistory.com/34&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/jeyF8/hyX7PrBfFI/J3OX6i9cvH4LkfUR92sPW1/img.png?width=280&amp;amp;height=280&amp;amp;face=0_0_280_280,https://scrap.kakaocdn.net/dn/bp2IYy/hyX7THxscQ/ksRnlCKbBsFOPLdfILMmqk/img.png?width=280&amp;amp;height=280&amp;amp;face=0_0_280_280,https://scrap.kakaocdn.net/dn/brCnH6/hyX4sEOMxg/DwacTweKJCwkDtAKJpr1QK/img.png?width=3029&amp;amp;height=475&amp;amp;face=0_0_3029_475');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[프론트엔드] 성능 최적화 정리&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;목차 0. 개요 1. 브라우저 동작 원리 2. 성능 최적화 2.1 페이지 로드 최적화 2.2 페이지 렌더링 최적화 3. 성능 측정 기준 3.1 브라우저 내부 이벤트 기준 3.2 사용자 기준 성능 지표 3.3 사용자 기준 성&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;coffeeandcakeandnewjeong.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://ui.toast.com/fe-guide/ko_PERFORMANCE&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://ui.toast.com/fe-guide/ko_PERFORMANCE&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1737966521193&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;성능 최적화&quot; data-og-description=&quot;애플리케이션 성능 최적화는 앱과 웹에서 모두 중요하다. 최근 웹 애플리케이션은 Ajax 통신, 복잡한 UI 등 많은 기능을 담으면서 크고 무거워졌다. 무거워진 웹은 긴 로딩 시간 함께 사용자 경험&quot; data-og-host=&quot;ui.toast.com&quot; data-og-source-url=&quot;https://ui.toast.com/fe-guide/ko_PERFORMANCE&quot; data-og-url=&quot;https://ui.toast.com/fe-guide/ko_PERFORMANCE/undefined/fe-guide/ko_PERFORMANCE&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/8AF6A/hyX7Xb6gMJ/8yCw2PBHhppxgvWYDODk4K/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/bh4RPg/hyX4sdOJWr/w0c4AxAAihtmbq2LaqvXr1/img.png?width=768&amp;amp;height=673&amp;amp;face=0_0_768_673,https://scrap.kakaocdn.net/dn/3pxii/hyX73pQGVb/qGmlzBt5lsCBlzVAsj08J0/img.png?width=582&amp;amp;height=299&amp;amp;face=0_0_582_299&quot;&gt;&lt;a href=&quot;https://ui.toast.com/fe-guide/ko_PERFORMANCE&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://ui.toast.com/fe-guide/ko_PERFORMANCE&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/8AF6A/hyX7Xb6gMJ/8yCw2PBHhppxgvWYDODk4K/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/bh4RPg/hyX4sdOJWr/w0c4AxAAihtmbq2LaqvXr1/img.png?width=768&amp;amp;height=673&amp;amp;face=0_0_768_673,https://scrap.kakaocdn.net/dn/3pxii/hyX73pQGVb/qGmlzBt5lsCBlzVAsj08J0/img.png?width=582&amp;amp;height=299&amp;amp;face=0_0_582_299');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;성능 최적화&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;애플리케이션 성능 최적화는 앱과 웹에서 모두 중요하다. 최근 웹 애플리케이션은 Ajax 통신, 복잡한 UI 등 많은 기능을 담으면서 크고 무거워졌다. 무거워진 웹은 긴 로딩 시간 함께 사용자 경험&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;ui.toast.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>STUDY/JavaScript</category>
      <category>브라우저</category>
      <category>성능최적화</category>
      <category>프론트엔드</category>
      <author>宋白手</author>
      <guid isPermaLink="true">https://ooo-k.tistory.com/453</guid>
      <comments>https://ooo-k.tistory.com/453#entry453comment</comments>
      <pubDate>Fri, 28 Jun 2024 10:24:07 +0900</pubDate>
    </item>
  </channel>
</rss>