<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>RPG처럼 웹 개발하기</title>
    <link>https://waterworkcode.tistory.com/</link>
    <description>배운것도, 깨달은것도 금방 잊어버리는 웹 개발자가 RPG 게임처럼 웹개발 능력을 성장시켜 나가는 과정을 기록하는 웹개발 스킬 정보창 같은 페이지입니다.</description>
    <language>ko</language>
    <pubDate>Sun, 15 Mar 2026 14:58:59 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>RPG 마니아</managingEditor>
    <image>
      <title>RPG처럼 웹 개발하기</title>
      <url>https://tistory1.daumcdn.net/tistory/4892025/attach/b9ea432bda4a475283ed0a8b58bd4334</url>
      <link>https://waterworkcode.tistory.com</link>
    </image>
    <item>
      <title>TypeScript 설정에 필수로 작성 해야 하는것</title>
      <link>https://waterworkcode.tistory.com/entry/TypeScript-%EC%84%A4%EC%A0%95%EC%97%90-%ED%95%84%EC%88%98%EB%A1%9C-%EC%9E%91%EC%84%B1-%ED%95%B4%EC%95%BC-%ED%95%98%EB%8A%94%EA%B2%83</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;TypeScript 프로젝트를 진행할때 ts.config 어떻게 설정해놓으셨나요?&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span&gt;지금까지 CRA 또는 Next에서 설정해준 기본값 그대로 진행하셨나요?&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;저는 처음에 기본값 설정 그대로 진행했었는데요&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;처음 기본값으로 넣고 진행해본 이후에 후회했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&quot;공식 문서 꼼꼼하게 더 읽어보고 프로젝트열껄...&quot;&amp;nbsp;하고 말이죠&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;물론 TypeScript를 아주 잘 알고, 아주 잘 사용하고 계시는 분들이 많으시지만,&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;저는 잘모르고 시작했었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;어떤 설정을 줘야하고 어떻게 시작해야하는지요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그래서 오늘은 제가 후회했던 첫 기본 설정에 대해 말씀드리려고 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;TypeScript를 사용하기 시작하신지 얼마 안되셨거나,&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이제 사용해보실 생각이라면 도움이 더 될것 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;일단 기본으로 설정해주는 ts.config설정을 먼저 보여드리겠습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;ts-config-capture.png&quot; data-origin-width=&quot;936&quot; data-origin-height=&quot;716&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/TLDDy/btrTKJRXtMt/xX28bJuska3Zs7AmbIFX3k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/TLDDy/btrTKJRXtMt/xX28bJuska3Zs7AmbIFX3k/img.png&quot; data-alt=&quot;CRA가 만들어주는 기본적인 ts.config.json 파일&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/TLDDy/btrTKJRXtMt/xX28bJuska3Zs7AmbIFX3k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTLDDy%2FbtrTKJRXtMt%2FxX28bJuska3Zs7AmbIFX3k%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;936&quot; height=&quot;716&quot; data-filename=&quot;ts-config-capture.png&quot; data-origin-width=&quot;936&quot; data-origin-height=&quot;716&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;CRA가 만들어주는 기본적인 ts.config.json 파일&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;size18&quot;&gt;그리고 오늘 제가 말씀드릴 설정은 &lt;b&gt;noImplicitAny&lt;/b&gt;, &lt;b&gt;strictNullChecks&lt;/b&gt; 설정입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;먼저 noImplicitAny 플래그부터 설명 드리겠습니다.&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;h2 data-ke-size=&quot;size26&quot;&gt;NoImplicitAny&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;TypeScript 에서는 타입 추론으로 대부분의 경우에서&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;타입을 명시적으로 선언하지 않아도,&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;TypeScript가 알아서 타입을 추론해 어떤 타입인지 알맞는 타입으로 선언이 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;하지만 몇몇의 경우에 TypeScript가 값의 타입을 추론하지 않고 any로 간주합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;JavaScript 관점으로 보았을때 모든 변수는 any 타입이기 때문에 큰 문제는 아닙니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그래도 저는 TypeScript 타입체크를 엄격하게 활성화해서&amp;nbsp;암묵적 any를 허용해주고 싶지 않습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;( 저뿐만 아니라 TypeScript를 사용하는 많은 프로그래머들이 원하는 것일겁니다. )&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;엄격하게 TypeScript 검사기를 사용하고 싶은 프로그래머 입장에서는 허용해주고 싶지 않고&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;암묵적인 any를 허용해주게 된다면 TypeScript를 사용하는 이유가 무색해집니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이런 경우에 noImplicitAny 플래그를 활성화하면 타입 추론이 되지 않고&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;any로 암묵적으로 추론되는 변수에 대하여 오류를 발생시킵니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;TypeScript로 프로젝트를 시작하는 경우에는 대부분 true 설정으로 시작합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;TypeScript로 프로젝트를 시작한다면 noImplicitAny 설정을 꼭 켜주는게 좋겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot;&gt;&lt;code&gt;{
  &quot;compilerOptions&quot;: {
	&quot;noImplicitAny&quot;: true,
	// ...
  },
  &quot;include&quot;: ...,
  &quot;exclude&quot;: ...,
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;strictNullChecks&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Null과 undefined의 처리를 잘한다면 정말 좋지만&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;생각보다 해당 부분을 놓치는 경우가 많습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;qml&quot;&gt;&lt;code&gt;const test: string = undefined;
const test2: string = null
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;위와 같은 코드를 쓰게되는 경우도 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;strictNullChecks 설정을 사용하면 위 코드가 에러 표시가 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot;&gt;&lt;code&gt;{
  &quot;compilerOptions&quot;: {
	&quot;strictNullChecks&quot;: true,
	// ...
  },
  &quot;include&quot;: ...,
  &quot;exclude&quot;: ...,
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;strictNullChecks&lt;span&gt;&amp;nbsp;&lt;/span&gt;플래그는 null과 undefined를 보다 명시적으로 처리하며,&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;null 과 undefined 처리를 잘 했는지 걱정하는것을 하지 않게 해줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;하지만 null, undefined를 사용해야 하는 경우도 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그럴때는 undefined를 사용하는것을 추천드립니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;null이 아니라 undefined를 사용하는것을 추천한다고 말하는 이유는&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;제 다른글에서 설명을 적어 두었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;a href=&quot;https://waterworkcode.tistory.com/entry/Null-vs-Undefind&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://waterworkcode.tistory.com/entry/Null-vs-Undefind&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1671151575529&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;Null vs Undefind&quot; data-og-description=&quot;용어설명 1. undefiend 어떠한 값도 할당되지 않아 자료형이 정해지지 않은 상태입니다. 2. null 자료형이 정해진(defined) 상태입니다. null 값이 할당된 상태입니다. Null 과 Undefined 코드로 비교하기 conso&quot; data-og-host=&quot;waterworkcode.tistory.com&quot; data-og-source-url=&quot;https://waterworkcode.tistory.com/entry/Null-vs-Undefind&quot; data-og-url=&quot;https://waterworkcode.tistory.com/entry/Null-vs-Undefind&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/zC3M1/hyQTGXNYVH/cXN15ICVBCUTItxxTpnGpk/img.jpg?width=640&amp;amp;height=427&amp;amp;face=35_224_133_388,https://scrap.kakaocdn.net/dn/jLG0n/hyQU167dHf/Y26WTuSyEmFfC8bWhTVE6k/img.jpg?width=640&amp;amp;height=427&amp;amp;face=35_224_133_388,https://scrap.kakaocdn.net/dn/5Acmj/hyQUSPQ4il/A3EeNkcMnc6PjKDyIsqSHk/img.jpg?width=502&amp;amp;height=614&amp;amp;face=230_96_266_135&quot;&gt;&lt;a href=&quot;https://waterworkcode.tistory.com/entry/Null-vs-Undefind&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://waterworkcode.tistory.com/entry/Null-vs-Undefind&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/zC3M1/hyQTGXNYVH/cXN15ICVBCUTItxxTpnGpk/img.jpg?width=640&amp;amp;height=427&amp;amp;face=35_224_133_388,https://scrap.kakaocdn.net/dn/jLG0n/hyQU167dHf/Y26WTuSyEmFfC8bWhTVE6k/img.jpg?width=640&amp;amp;height=427&amp;amp;face=35_224_133_388,https://scrap.kakaocdn.net/dn/5Acmj/hyQUSPQ4il/A3EeNkcMnc6PjKDyIsqSHk/img.jpg?width=502&amp;amp;height=614&amp;amp;face=230_96_266_135');&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;Null vs Undefind&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;용어설명 1. undefiend 어떠한 값도 할당되지 않아 자료형이 정해지지 않은 상태입니다. 2. null 자료형이 정해진(defined) 상태입니다. null 값이 할당된 상태입니다. Null 과 Undefined 코드로 비교하기 conso&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;waterworkcode.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;읽어보시면 왜 undefined를 사용하는것을 추천하는지 바로 이해가 가실겁니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;물론 저보다 똑똑한 여러분들은 이미 다 알고계시겠지만요!&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그래서...&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이것으로 오늘 말씀드리려고 한&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;noImplicitAny&lt;/b&gt;&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;strictNullChecks&lt;/b&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;설정에 대해 모두 이야기해봤습니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span&gt;&lt;span&gt;TypeScript를 처음 사용하시거나, 아직 잘 모르시는 입장에서는,&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;직접 사용해보는것이 아니라면 대체 무엇인지&amp;nbsp;눈으로 보고 한번에 알기 어려우실 겁니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;저도 그랬으니까요!&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그래서 지금 진행하고 계신 프로젝트, 또는 다음 프로젝트에서&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;해당 설정을 켜고 프로젝트를 진행해 보시는것을 추천드립니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;우리는 혼자 코드를 작성하고 프로젝트를 진행하는것이 아니라,&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;다른 개발자들과 협업하고 그들과 서로 이해할 수 있는 코드를 작성해야하며&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;TypeScript의 의도처럼 유연함을 조금 덜어내고 버그, 오류를 잡아내고 싶으니까요...!&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그럼 다같이 화이팅!!!&lt;/p&gt;</description>
      <category>웹 개발</category>
      <category>ts 기초 설정</category>
      <category>ts 설정</category>
      <category>ts 설정값</category>
      <category>ts 프로젝트 설정 추천</category>
      <category>ts 필수 설정</category>
      <category>ts.config.json</category>
      <category>ts.config.json default setting</category>
      <category>TypeScript config</category>
      <category>타입스크립트 설정값</category>
      <category>타입스크립트 필수 설정</category>
      <author>RPG 마니아</author>
      <guid isPermaLink="true">https://waterworkcode.tistory.com/14</guid>
      <comments>https://waterworkcode.tistory.com/entry/TypeScript-%EC%84%A4%EC%A0%95%EC%97%90-%ED%95%84%EC%88%98%EB%A1%9C-%EC%9E%91%EC%84%B1-%ED%95%B4%EC%95%BC-%ED%95%98%EB%8A%94%EA%B2%83#entry14comment</comments>
      <pubDate>Fri, 16 Dec 2022 07:20:56 +0900</pubDate>
    </item>
    <item>
      <title>Null vs Undefind</title>
      <link>https://waterworkcode.tistory.com/entry/Null-vs-Undefind</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;용어설명&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. undefiend&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;어떠한 값도 할당되지 않아 자료형이 정해지지 않은 상태입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. null&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;자료형이 정해진(defined) 상태입니다.&lt;/li&gt;
&lt;li&gt;null 값이 할당된 상태입니다.&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;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Null 과 Undefined 코드로 비교하기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;coffeescript&quot;&gt;&lt;code&gt;console.log(null == null); // true
console.log(undefined == undefined); // true
console.log(null == undefined); // true

console.log(null === null); // true
console.log(undefined === undefined); // true
console.log(null === undefined); // 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;null == undefined 결과가 true이기 때문에 작성 가능한 코드&lt;/p&gt;
&lt;pre class=&quot;coffeescript&quot;&gt;&lt;code&gt;const foo = (arg: string | null | undefined) =&amp;gt; {
	if (arg == null) {
		// null 또는 undefined 값이 매개변수로 들어왔습니다.
	} else {
		console.log(arg);
	}
}

&lt;/code&gt;&lt;/pre&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;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Null 과 Undefined 어떤걸 사용해야 하지?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Typescript 공식 문서를 보면 아래와 같이 나와 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;undefined&lt;/b&gt; &lt;/span&gt;를 사용하고 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;null&lt;/b&gt;&lt;/span&gt; 을 사용하지 마세요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;null 을 사용하지말고 undefined 를 사용하라고 하는 문서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/Microsoft/TypeScript/wiki/Coding-guidelines#null-and-undefined&quot;&gt;Coding guidelines &amp;middot; microsoft/TypeScript Wiki&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1668927708797&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - microsoft/TypeScript: TypeScript is a superset of JavaScript that compiles to clean JavaScript output.&quot; data-og-description=&quot;TypeScript is a superset of JavaScript that compiles to clean JavaScript output. - GitHub - microsoft/TypeScript: TypeScript is a superset of JavaScript that compiles to clean JavaScript output.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/Microsoft/TypeScript/wiki/Coding-guidelines#null-and-undefined&quot; data-og-url=&quot;https://github.com/microsoft/TypeScript&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bDAglx/hyQDzpOz0J/05meP8RTU7H2HtGWk9MG80/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/Microsoft/TypeScript/wiki/Coding-guidelines#null-and-undefined&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/Microsoft/TypeScript/wiki/Coding-guidelines#null-and-undefined&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bDAglx/hyQDzpOz0J/05meP8RTU7H2HtGWk9MG80/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - microsoft/TypeScript: TypeScript is a superset of JavaScript that compiles to clean JavaScript output.&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;TypeScript is a superset of JavaScript that compiles to clean JavaScript output. - GitHub - microsoft/TypeScript: TypeScript is a superset of JavaScript that compiles to clean JavaScript output.&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;null 은 나쁜 아이디어!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure data-ke-type=&quot;video&quot; data-ke-style=&quot;alignCenter&quot; data-video-host=&quot;youtube&quot; data-video-url=&quot;https://www.youtube.com/watch?v=PSGEjv3Tqo0&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/cGiwAN/hyQDyqTITW/qQEa849K1lQKkFjzwWcwHK/img.jpg?width=1050&amp;amp;height=576&amp;amp;face=415_85_510_188&quot; data-video-width=&quot;860&quot; data-video-height=&quot;472&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;472&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/PSGEjv3Tqo0&quot; width=&quot;860&quot; height=&quot;472&quot; frameborder=&quot;&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;
&lt;figcaption&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;알고 있으면 좋은 점 ( 근데 주관적인 생각도 좀 들어간&amp;hellip; )&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;undefined 를 명시적으로 선언해주는것은 좋지 않습니다.&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;undefined는 변수는 존재하나, 어떠한 값도 할당되지 않은 상태라는 말 입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;의도적으로 undefined 를 선언해서 사용하는것은 옳지 않습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;의도적으로 undefined 값을 주는것 이라면 차라리 null 을 주는것이 낫다고 생각합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;하지만 더 좋은 방법은 그냥 값을 주지 않는것이죠.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;어차피 참조하려고 하면 undefined를 자동으로 뱉을테니까요.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;const badItem = { a: 1, b: undefined };    // bad
const goodItem = { a: 1 };                 // good
&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;/p&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://basarat.gitbook.io/typescript/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://basarat.gitbook.io/typescript/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1668927759780&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;README - TypeScript Deep Dive&quot; data-og-description=&quot;Share URL: https://basarat.gitbook.io/typescript/&quot; data-og-host=&quot;basarat.gitbook.io&quot; data-og-source-url=&quot;https://basarat.gitbook.io/typescript/&quot; data-og-url=&quot;https://basarat.gitbook.io/typescript/&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://basarat.gitbook.io/typescript/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://basarat.gitbook.io/typescript/&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;README - TypeScript Deep Dive&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Share URL: https://basarat.gitbook.io/typescript/&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;basarat.gitbook.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;</description>
      <category>웹 개발</category>
      <category>null</category>
      <category>Null vs Undefined</category>
      <category>TypeScript</category>
      <category>TypeScript Deep Dive</category>
      <category>TypeScript Undefined Null</category>
      <category>undefined</category>
      <category>고민</category>
      <category>공부</category>
      <author>RPG 마니아</author>
      <guid isPermaLink="true">https://waterworkcode.tistory.com/13</guid>
      <comments>https://waterworkcode.tistory.com/entry/Null-vs-Undefind#entry13comment</comments>
      <pubDate>Thu, 24 Nov 2022 20:00:09 +0900</pubDate>
    </item>
    <item>
      <title>Interface VS Type alias 비교하기</title>
      <link>https://waterworkcode.tistory.com/entry/Interface-VS-Type-alias-%EB%B9%84%EA%B5%90%ED%95%98%EA%B8%B0</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;p data-ke-size=&quot;size16&quot;&gt;이 글을 읽으려고 들어오신 분들은 TypeScript를 사용하여 코드를 작성하시는 분이거나,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TypeScript를 사용하기 위해 알아보기 위한 분들이실겁니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일단 저는 TypeScript 를 천천히 도입해보고 있는 개발자입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TypeScript 를 천천히 공부하며 사용해보고 있는 와중에 저는 의문이 생겼습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;ldquo;Interface 그리고 Type alias 이것들은 대체 무엇이 어떻게 다른것이지?&amp;rdquo; 라는 의문 말이죠.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러분은 Interface 와 Type alias 의 차이를 잘 알고 계신가요?&lt;/p&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;잘 모르겠거나, 헷갈리는분들, 그리고 이미 알고 계시는 분들도 차근차근 보면서 같이 정리해볼까요?&lt;/p&gt;
&lt;p data-ke-size=&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;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;용어설명&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. Type Alias&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;한국어로 &amp;ldquo;타입 별칭&amp;rdquo; 이라고 번역되어 사용 되어지고 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot;&gt;&lt;code&gt;type Name = string;

type ExplainType = {
	id: number;
	name: Name;
};

// 위처럼 사용할 수 있는 형태입니다.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. Interface&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;객체 형태로만 정의가 가능합니다.&lt;/li&gt;
&lt;li&gt;한국어로 &amp;ldquo;인터페이스&amp;rdquo; 영어를 그대로 읽어서 사용 되어지고 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1668920998734&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;interface IExplainType {
	id: number;
	name: string;
};

// 위와 같은 형태입니다.
// 선언할때 IObject 처럼 앞에 주로 대문자 I 를 붙여서 사용합니다. (인터페이스 라는 뜻 입니다.)&lt;/code&gt;&lt;/pre&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;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;무엇이 다른지 일단 나열!&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Interface 는 객체 형태만 타입 설정이 가능하다.&lt;/li&gt;
&lt;li&gt;Computed Property&lt;/li&gt;
&lt;li&gt;타입 프리뷰&lt;/li&gt;
&lt;li&gt;확장&lt;/li&gt;
&lt;/ol&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;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Type Preview ( 타입 미리보기 )&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Interface로 타입을 정의 한 경우에는 Type Preview 창이 나오지 않습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 Type Alias로 타입을 정의한 경우에는 Type Preivew 를 사용할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/63tMT/btrRC08U27T/HeZKTOwhzaNzOHheKNQqIk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/63tMT/btrRC08U27T/HeZKTOwhzaNzOHheKNQqIk/img.png&quot; data-is-animation=&quot;false&quot; data-origin-width=&quot;398&quot; data-origin-height=&quot;198&quot; data-filename=&quot;type-alias.png&quot; style=&quot;width: 49.2023%; margin-right: 10px;&quot; data-widthpercent=&quot;49.78&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/63tMT/btrRC08U27T/HeZKTOwhzaNzOHheKNQqIk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F63tMT%2FbtrRC08U27T%2FHeZKTOwhzaNzOHheKNQqIk%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;398&quot; height=&quot;198&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cvW28d/btrRzZKex7p/1YFGKsYyodezyHiD9NfPN1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cvW28d/btrRzZKex7p/1YFGKsYyodezyHiD9NfPN1/img.png&quot; data-is-animation=&quot;false&quot; data-origin-width=&quot;438&quot; data-origin-height=&quot;216&quot; data-filename=&quot;interface.png&quot; style=&quot;width: 49.6349%;&quot; data-widthpercent=&quot;50.22&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cvW28d/btrRzZKex7p/1YFGKsYyodezyHiD9NfPN1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcvW28d%2FbtrRzZKex7p%2F1YFGKsYyodezyHiD9NfPN1%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;438&quot; height=&quot;216&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;왼쪽 : Type Alias&amp;nbsp; 오른쪽 : Interface&amp;nbsp; &amp;nbsp; &amp;nbsp; 미리보기 기능 비교&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;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;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Index Signature 란?&lt;/h2&gt;
&lt;pre class=&quot;processing&quot;&gt;&lt;code&gt;type ObjectType = {
	[key: stirng]: string;
};

// 위와 같은 형식으로 object 에서 어떤 값이 들어올지 모를때 주로 사용된다.
const key = 'signature';
const targetObject: ObjectType = {
	'signature': 'Hello!',
};

console.log(targetObject[key]);
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;객체의 속성을 알 수 없는 상황일때만 사용하는것이 좋다고 생각합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;객체를 Index Signature 를 사용한다면 에러는 발생하지 않겠지만 존재하지 않는 키값을 참조하는 상황이 발생할 수도 있고,&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;타입을 선언하기 어려운경우에만 Index Signature 를 사용하는것이 좋다고 생각합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;String, Number, Symbols 타입만 가능합니다.&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;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Computed Property&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Computed Property 라고 부르는 분도 있고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Computed Value , Template literal 이라고 부르는 분도 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저는 이글에서는 일단 Computed Property 라고 불러보겠습니다.&lt;/p&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 class=&quot;routeros&quot;&gt;&lt;code&gt;type Name = 'si' | 'bi' | 'pi';

type ObjectType = {
	[key in Name]: string;
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Index Signature 와 비슷하게 생겼습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저는 처음에 &amp;ldquo;Index Signature 하고 뭐가 다른거지? 다른 이름인데 똑같은 건가?&amp;rdquo; 라고 생각했었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;근데 자세히 보니까 [key in Name] 이 부분이 달랐습니다. 들어올 key 값을 정해 놓는 형태입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;crmsh&quot;&gt;&lt;code&gt;// Index Signature
type IndexSignature = {
	[key: string]: string;
};

// Computed Property
type order = 'app' | 'web' | 'appWeb';
type ComputedProperty = {
	[key in order]: string;
}
&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;Index Signature 는 interface, type alias 둘 다 사용 가능하지만,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Computed Property 는 type alias 에서만 사용 가능합니다!&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;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;타입 확장을 하는 방법&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Interface 의 경우&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;interface INav {
	state: string;
};

interface ISidenav extends INav {
	isActive: boolean;
};

// 위 형태로 주로 확장을 하는데 애래처럼 똑같은 이름으로 재선언하면 자동적으로 합체시켜준다.
// 이를 선언 병합이라고 합니다.

interface INav {
	isActive: boolean;
};

// 근데 개인적으로 extends로 확장해주는게 좋다고 생각이 듭니다.
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Type Alias 의 경우&lt;/p&gt;
&lt;pre class=&quot;elm&quot;&gt;&lt;code&gt;type Nav = {
	state: string;
};

type Sidenav = Nav &amp;amp; {
	isActive: boolean;
};
// interface처럼 재선언해서 확장을 하는방식은 불가능하다.
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;엄밀히 말하면 Type Alias 의 경우 Interface 처럼 확장이 되는것은 아닙니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Type Alias는 확장을 하는것이 아니라, 타입을 더해서 새로운 타입을 정의하는 방식입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 코드로 보면 선언된 Nav 타입과 isActive 를 더해서 새로운 타입을 만들어내는 건데요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공식 문서를 보면 &amp;amp; 를 사용해서 Type을 더해 새로운 타입을 만들어낸다면 의도치 않은 버그가 생길수 있다고 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Type Alias는 Interface 처럼 확장해주는 것이 아니라&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Type Alias 는 모두 다 한번씩 돌면서 선언된 타입과 &amp;amp; 를 사용하여 정의된 타입을 더해주는것이기 때문에,&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;성능상으로도 interface가 더 좋습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;확장 부분은 interface의 압승이네요!&lt;/p&gt;
&lt;p data-ke-size=&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;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Type Alias 의 문제점&lt;/h2&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;확장의 경우 Interface는 단순 객체만 들어오기 때문에 합치기만 하면 되는데, Type Alias는 순회 하면서 속성을 합쳐주기 때문에 충돌날 수 있습니다.&lt;/li&gt;
&lt;li&gt;Interface 를 합칠경우 캐시가 되지만, Type 의 경우 모든 구성요소의 Type 을 체크하기 때문에 컴파일시 상대적으로 성능이 좋지 않습니다.&lt;/li&gt;
&lt;/ol&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;style5&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;그래서 제 개인적인 생각은&amp;hellip;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일단 공식 문서에서는 특별한 경우를 제외하고 interface 를 추천하고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;근데 Type Alias 에서만 가능한것들이 존재합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Interface는 불가능한 객체가 아닌 타입을 정의하거나,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Indexed Signature 또는 Computed Property 를 사용하는 상황일때는 Type Alias를 사용하는것도 좋다고 생각합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;저는 아래와 같은 방법을 사용할것 같습니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;팀에서 기본적으로 Interface 를 사용하여 타입을 선언한다.&lt;/li&gt;
&lt;li&gt;단일 타입을 선언하는 경우 Type Alias 를 사용한다.&lt;/li&gt;
&lt;li&gt;Index Signature, Computed Property 를 사용할때는 Type Alias 를 사용한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;결론적으로 중요한것은, 팀에서 약속을 정해서 사용하는것이 제일 중요하다고 생각합니다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1번 개발자는 어떤 이유로 Interface 를 선호해서 사용하고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2번 개발자는 어떤 이유로 Type Alias 를 사용하더라도,&lt;/p&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번 개발자가 같이 작업할때 어떻게 하겠다!&lt;/p&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;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참조 페이지 :&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.typescriptlang.org/docs/handbook/declaration-files/by-example.html#reusable-types-interfaces&quot;&gt;Documentation - Declaration Reference&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.typescriptlang.org/docs/handbook/intro.html&quot;&gt;Handbook - The TypeScript Handbook&lt;/a&gt;&lt;/p&gt;</description>
      <category>웹 개발</category>
      <category>Interface</category>
      <category>Interface vs Type Alias</category>
      <category>Type alias</category>
      <category>TypeScript</category>
      <category>Typescript Handbook</category>
      <category>Typescript Study</category>
      <category>why use interface?</category>
      <category>공부</category>
      <category>인터페이스 vs 타입</category>
      <category>인터페이스 타입 비교</category>
      <author>RPG 마니아</author>
      <guid isPermaLink="true">https://waterworkcode.tistory.com/12</guid>
      <comments>https://waterworkcode.tistory.com/entry/Interface-VS-Type-alias-%EB%B9%84%EA%B5%90%ED%95%98%EA%B8%B0#entry12comment</comments>
      <pubDate>Sun, 20 Nov 2022 14:43:30 +0900</pubDate>
    </item>
    <item>
      <title>Blob으로 이미지 업로드 훑어보기</title>
      <link>https://waterworkcode.tistory.com/entry/Blob%EC%9C%BC%EB%A1%9C-%EC%9D%B4%EB%AF%B8%EC%A7%80-%EC%97%85%EB%A1%9C%EB%93%9C-%ED%9B%91%EC%96%B4%EB%B3%B4%EA%B8%B0</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;들어가기 전 용어 정리!&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Blob &amp;rarr; ( Binary Large OBject ) 의 앞 단어들을 따와서 만든 축약어 입니다.&lt;/li&gt;
&lt;li&gt;Binary &amp;rarr; 이진법을 의미합니다. ( 1010011 )&lt;/li&gt;
&lt;li&gt;Object &amp;rarr; 말 그대로 객체입니다.&lt;/li&gt;
&lt;li&gt;청크 &amp;rarr; 데이터 덩어리입니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Blob이란?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Binary Large Object.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단어 그대로 &lt;b&gt;이진수로 이루어진 큰 객체&lt;/b&gt;라는 뜻 입니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;JS 에서 Blob이 사용되는 이유?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이미지, 동영상, 등 멀티미디어 데이터를 다룰때 사용합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프론트엔드에서 Blob은 보통 서버에 이미지, 동영상을 올리거나,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서버에서 Blob 형태의 이미지 파일을 받아와서 사용하는 형태로 사용이 되고 있습니다.&lt;/p&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;그리고 Blob 형태의 이미지를 미리볼 수 있도록 만들어 보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 이제 Blob을 이해하기 쉽게 작성해보겠습니다.&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;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;이미지를 Blob으로 만들기!&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;아래 코드들은 비효율적이며, 좋은 코드가 아닙니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;Blob을 설명하기 위한 코드들 입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저는 이미지를 가지고 Blob 을 만들것이기 때문에,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이미지 파일을 만질 수 있도록 html을 작성해보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;ada&quot;&gt;&lt;code&gt;&amp;lt;body&amp;gt;
	&amp;lt;input type=&quot;file&quot; accept=&quot;image/*&quot; &amp;gt;
&amp;lt;body/&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;JS를 통해서 만들 수 있기 때문에 위에 작성한 input을 만질 수 있는 코드를 작성해보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;typescript&quot;&gt;&lt;code&gt;const inputFileTag = document.querySelector('input');

const changeFileHandle = (e) =&amp;gt; {
  const file = e.target.files[0];
  const blob = new Blob([file], { type: 'image/png' });
	console.log(blob);
};

inputFileTag.addEventListener('change', changeFileHandle);
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 코드로 아주 간단하게 이미지를 Blob으로 만들 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러면 왜 Blob으로 만드는걸까요?&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;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Blob 을 사용하는 이유?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;브라우저에 Blob으로 저장된 파일이 있을때, 서버에 추가요청 없이 파일을 보여줄 수 있습니다.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;URL.createObjectURL(blob)&lt;/span&gt; 을 사용해서 URL 을 사용할 수 있어서, 미리보기처럼 보여줄 수 있습니다.&lt;/li&gt;
&lt;/ol&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;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;변수에 이미지 파일을 담을 수 있기 때문입니다&lt;/b&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;변수에 이미지 파일이 담겼으면 이제 이미지를 기존보다 더 정교하게 만질 수 있다는 뜻입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;base64, ArrayBuffer, FileRead 등을 통해서 여러가지 작업을 할 수 있습니다.&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;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;사진 업로드 전 미리보기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서 적었던 &lt;span style=&quot;background-color: #dddddd;&quot;&gt;URL.createObjectURL(blob)&lt;/span&gt; 을 사용해서 URL 을 생성할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;const inputFileTag = document.querySelector('input');

const changeFileHandle = (e) =&amp;gt; {
  const file = e.target.files[0];
	const url = URL.createObjectURL(blob);
  console.log(url);
};

inputFileTag.addEventListener('change', changeFileHandle);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;ada&quot;&gt;&lt;code&gt;&amp;lt;body&amp;gt;
	&amp;lt;input type=&quot;file&quot; accept=&quot;image/*&quot; &amp;gt;
	&amp;lt;img src=&quot;&quot; /&amp;gt;
&amp;lt;body/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;qml&quot;&gt;&lt;code&gt;const inputFileTag = document.querySelector('input');
const imgTag = document.querySelector('img');

const changeFileHandle = (e) =&amp;gt; {
  const file = e.target.files[0];
	const url = URL.createObjectURL(blob);
	imgTag.src = url;
  console.log(url);
};

inputFileTag.addEventListener('change', changeFileHandle);
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 코드처럼 미리보기를 보여줄 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 URL을 사용하고 난 뒤, 필요 없어졌을때 &lt;span style=&quot;background-color: #dddddd;&quot;&gt;URL.revokeObjectURL(url)&lt;/span&gt; 을 통해서 생성한 URL을 제거해주는것이 좋습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문서가 언로드될 때 객체 URL을 자동으로 해제하지만,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최적의 성능과 메모리 사용을 위해 명시적으로 언로드할 수 있는 안전한 시간이 있다면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;URL.revokeObjectURL(url)&lt;/span&gt; 코드를 통해 언로드 해야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 서버로 데이터를 보낼때는 기존 방식과 어떻게 다를까요?&lt;/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;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;기존에 이미지를 서버에 보내는 방법&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보통은 Blob 으로 만들어서 서버에 보내는 형태가 아니라&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;new FormData()&lt;/span&gt; 를 만든 뒤, Input 태그에 files을 FormData에 넣어주고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 FormData를 서버에 보내는 형태로 작성을 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;dart&quot;&gt;&lt;code&gt;const inputFileTag = document.querySelector('input');

const changeFileHandle = (e) =&amp;gt; {
	// 하나의 이미지만 넣어줄거라 files[0]으로 고정했습니다.
  const file = e.target.files[0];
	const formData = new FormData();
	formData.append('file', file);
	// fetch!
};

inputFileTag.addEventListener('change', changeFileHandle);
&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: #dddddd;&quot;&gt;const file = e.target.files[0];&lt;/span&gt; 코드가 실행되면 file 변수에 사용자가 넣어준 File이 들어가게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 file 변수에는 파일의 최종 수정일, 이름, 크기, 타입 등의 데이터가 들어가 있습니다.&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;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Blob을 서버에 보내는 방법&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서 보내는 방식과 거의 동일합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다른점은 FormData를 만들지만 이번에는 File이 아니라 Blob으로 변환해서 넣어주는것 입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;typescript&quot;&gt;&lt;code&gt;const inputFileTag = document.querySelector('input');

const changeFileHandle = (e) =&amp;gt; {
	// 하나의 이미지만 넣어줄거라 files[0]으로 고정했습니다.
  const file = e.target.files[0];
  const blob = new Blob([file], { type: 'image/png' });
	const formData = new FormData();
	formData.append('blob', blob);
	// fetch!
};

inputFileTag.addEventListener('change', changeFileHandle);
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;결론적으로 제 생각은&amp;hellip;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특별한 상황이 없이, 멀티미디어 데이터를 서버에 보내주는 입장이라면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Blob을 만들어서 보내줄 필요 없이, 그냥 FormData 에 File 을 담아서 보내주면 된다고 생각합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서버에서 받는 입장일때도 보통은, 서버가 AWS S3의 이미지 주소를 보내주면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 주소를 img 태그의 src로 적어주면 된다고 생각합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결론적으로 필요한 상황에만 Blob을 사용하는게 좋다고 생각합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면 Blob은 어떤 상황에 사용했을때 장점을 발휘할 수 있을까요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;바로 파일이 너무 큰 경우라고 생각합니다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파일이 너무 큰경우, slice를 사용해서 파일을 나누어서 서버에 전달할 수 있기 때문입니다.&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;주로 파일이 크거나, 다른 특정한 이유가 있을때 Blob을 사용한다고 생각했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;큰 멀티미디오 파일을 다룰때 더 자세하게 Blob을 알아보도록 하겠습니다 ^^&lt;/p&gt;
&lt;p data-ke-size=&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;span style=&quot;color: #9d9d9d;&quot;&gt;제가 이해한 정보가 잘못되었거나 틀린부분이 있으다면 댓글로 알려주신다면 언제나 오예입니다 ^__^&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&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://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL&lt;/a&gt;&lt;/p&gt;</description>
      <category>웹 개발</category>
      <category>Blob</category>
      <category>Blob 사용하는 이유</category>
      <category>Blob 청크</category>
      <category>Blob?</category>
      <category>Blob이란?</category>
      <category>JS Blob</category>
      <category>JS 이미지 미리보기</category>
      <category>이미지 서버에 업로드</category>
      <category>이미지 압축</category>
      <category>프론트 이미지 업로드</category>
      <author>RPG 마니아</author>
      <guid isPermaLink="true">https://waterworkcode.tistory.com/11</guid>
      <comments>https://waterworkcode.tistory.com/entry/Blob%EC%9C%BC%EB%A1%9C-%EC%9D%B4%EB%AF%B8%EC%A7%80-%EC%97%85%EB%A1%9C%EB%93%9C-%ED%9B%91%EC%96%B4%EB%B3%B4%EA%B8%B0#entry11comment</comments>
      <pubDate>Sun, 2 Oct 2022 14:17:43 +0900</pubDate>
    </item>
    <item>
      <title>PWA 푸시알림 어떻게 구현하지?</title>
      <link>https://waterworkcode.tistory.com/entry/PWA-%ED%91%B8%EC%89%AC-%EC%95%8C%EB%A6%BC-%EB%B3%B4%EB%82%B4%EA%B8%B0</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;웹에서 푸시 알림을 보내야하는데 어떻게 보내는지 모르시겠나요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PWA 로 푸시 알림을 넣고 싶은데 대체 어떻게 하라는건지 하나도 모르시겠나요?&lt;/p&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;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;PWA 프로젝트를 진행할때는 처음부터 템플릿을 사용해서 프로젝트를 여는것이 편하고 좋습니다!&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;dsconfig&quot;&gt;&lt;code&gt;npx create-react-app &amp;lt;project-name&amp;gt; --template cra-template-pwa
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 index.js 파일에서 &lt;span style=&quot;color: #666666;&quot;&gt;serviceWorkerRegistration.register();&lt;/span&gt; 를 실행해줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;serviceWorkerRegistration.unregister();&lt;/span&gt;&amp;nbsp; &amp;rarr;&amp;nbsp; &lt;span style=&quot;color: #9d9d9d;&quot;&gt;serviceWorkerRegistration.register();&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;pwa_1.png&quot; data-origin-width=&quot;690&quot; data-origin-height=&quot;421&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cx8AXW/btrLlGvmu5W/LVee19ZSwmHqWLaijy234K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cx8AXW/btrLlGvmu5W/LVee19ZSwmHqWLaijy234K/img.png&quot; data-alt=&quot;src/index.js&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cx8AXW/btrLlGvmu5W/LVee19ZSwmHqWLaijy234K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcx8AXW%2FbtrLlGvmu5W%2FLVee19ZSwmHqWLaijy234K%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;690&quot; height=&quot;421&quot; data-filename=&quot;pwa_1.png&quot; data-origin-width=&quot;690&quot; data-origin-height=&quot;421&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;src/index.js&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;이후 serviceWorkerRegistration.js 파일에서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;contentType 을 콘솔로 찍어서 javascript 가 나오는지 확인합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;pwa_2.png&quot; data-origin-width=&quot;692&quot; data-origin-height=&quot;515&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lakS7/btrLh8T2ghV/pRed7dqacY2exdwQHpmOV0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lakS7/btrLh8T2ghV/pRed7dqacY2exdwQHpmOV0/img.png&quot; data-alt=&quot;src/serviceWorkerRegistration.js&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lakS7/btrLh8T2ghV/pRed7dqacY2exdwQHpmOV0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlakS7%2FbtrLh8T2ghV%2FpRed7dqacY2exdwQHpmOV0%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;692&quot; height=&quot;515&quot; data-filename=&quot;pwa_2.png&quot; data-origin-width=&quot;692&quot; data-origin-height=&quot;515&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;src/serviceWorkerRegistration.js&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;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;여기서!!&lt;/b&gt; &lt;/span&gt;위에 contentType 값이 만약 text/html 값이 나온다면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;npm run start 로 시작하면 안됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;npm run build&lt;/span&gt; &amp;rarr; &lt;span style=&quot;color: #9d9d9d;&quot;&gt;npx serve -s build&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 단계로 실행해주어야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;s&gt;( 여기서 아주 많은 삽질을&amp;hellip; )&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 firebase 프로젝트 만들어줍니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;pwa_3.png&quot; data-origin-width=&quot;1463&quot; data-origin-height=&quot;670&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0csw5/btrLipVBzHN/FxJj06GYl4ubmubjgFx9z0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0csw5/btrLipVBzHN/FxJj06GYl4ubmubjgFx9z0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0csw5/btrLipVBzHN/FxJj06GYl4ubmubjgFx9z0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0csw5%2FbtrLipVBzHN%2FFxJj06GYl4ubmubjgFx9z0%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;1463&quot; height=&quot;670&quot; data-filename=&quot;pwa_3.png&quot; data-origin-width=&quot;1463&quot; data-origin-height=&quot;670&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;프로젝트 설정 부분의 SDK 설정 및 구성을 확인합니다. ( 캡쳐한 사진 아래에 설정 값들이 들어가 있습니다. )&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;pwa_4.png&quot; data-origin-width=&quot;1870&quot; data-origin-height=&quot;788&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ev90n6/btrLnsji7Um/JRAROyP0VuyNscBlU26JWK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ev90n6/btrLnsji7Um/JRAROyP0VuyNscBlU26JWK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ev90n6/btrLnsji7Um/JRAROyP0VuyNscBlU26JWK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fev90n6%2FbtrLnsji7Um%2FJRAROyP0VuyNscBlU26JWK%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;1870&quot; height=&quot;788&quot; data-filename=&quot;pwa_4.png&quot; data-origin-width=&quot;1870&quot; data-origin-height=&quot;788&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다시 프로젝트로 들어와서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;npm install firebase&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;firebase 모듈을 다운받아줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;public 폴더 경로에 firebase-messaging-sw.js 파일을 생성합니다..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;import { initializeApp } from &amp;lsquo;firebase/app&amp;rsquo;&lt;/span&gt; 이렇게 넣으면 에러나서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;importScripts() 형태로 넣습니다.&lt;/p&gt;
&lt;pre class=&quot;reasonml&quot;&gt;&lt;code&gt;// public/firebase-messaging-sw.js 파일입니다
importScripts('&amp;lt;https://www.gstatic.com/firebasejs/9.0.0/firebase-app-compat.js&amp;gt;');
importScripts('&amp;lt;https://www.gstatic.com/firebasejs/9.0.0/firebase-messaging-compat.js&amp;gt;');

const firebaseConfig = {
  apiKey: &quot;firebase 에 있는 키&quot;,
  authDomain: &quot;window-pwa-test.firebaseapp.com&quot;,
  projectId: &quot;window-pwa-test&quot;,
  storageBucket: &quot;window-pwa-test.appspot.com&quot;,
  messagingSenderId: &quot;firebase에 있는 아이디&quot;,
  appId: &quot;firebase 에 있는 아이디&quot;,
  measurementId: &quot;firebase 에 있는 아이디&quot;
};

// firebase 시팅
firebase.initializeApp(firebaseConfig);
const messaging = firebase.messaging();
//백그라운드 서비스워커 설정
messaging.onBackgroundMessage(messaging, (payload) =&amp;gt; {
  console.log(&quot;[firebase - messaging - sw.js] Received background message&quot;,
    payload
  );
  // 푸시알람 설정
  const notificationTitle = &quot;Background Message&quot;;
  const notificationOptions = {
    body: payload,
    // icon: &quot;icon.png&quot;,
  };
  self.registration.showNotification(notificationTitle, notificationOptions);
});
&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;src 폴더 경로에 fcm.js 파일을 생성합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;typescript&quot;&gt;&lt;code&gt;import { initializeApp } from &quot;firebase/app&quot;;
import { getMessaging, getToken, onMessage } from &quot;firebase/messaging&quot;;

const firebaseConfig = {
  apiKey: &quot;firebase 에 있는 키&quot;,
  authDomain: &quot;window-pwa-test.firebaseapp.com&quot;,
  projectId: &quot;window-pwa-test&quot;,
  storageBucket: &quot;window-pwa-test.appspot.com&quot;,
  messagingSenderId: &quot;firebase에 있는 아이디&quot;,
  appId: &quot;firebase 에 있는 아이디&quot;,
  measurementId: &quot;firebase 에 있는 아이디&quot;
};

const app = initializeApp(firebaseConfig);
// 위에 initializeApp 안해주니까 콘솔에서 에러가 나서 해줬습니다.

const messaging = getMessaging();

//토큰값 얻기
getToken(messaging, {
  vapidKey: &quot;웹 푸시 인증서&quot;,
})
  .then((currentToken) =&amp;gt; {
    if (currentToken) {
      localStorage.setItem('notification-token', currentToken)
      console.log(currentToken);
    } else {
      console.log(
        &quot;No registration token available. Request permission to generate one.&quot;
      );
    }
  })
  .catch((err) =&amp;gt; {
    console.log(&quot;An error occurred while retrieving token.&quot;, err);
  });

onMessage(messaging, (payload) =&amp;gt; {
    console.log(&quot;Message received.&quot;, payload);
});
&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;여기서 로컬 스토리지에 넣어주는 currentToken 이 중요합니다.&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;vapidKey: &amp;ldquo;웹 푸시 인증서&amp;rdquo; 구간에는&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;pwa_5.png&quot; data-origin-width=&quot;2636&quot; data-origin-height=&quot;528&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b9z0es/btrLkaKpeo4/AQK6zc6o5eAtoyOOumC4rk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b9z0es/btrLkaKpeo4/AQK6zc6o5eAtoyOOumC4rk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b9z0es/btrLkaKpeo4/AQK6zc6o5eAtoyOOumC4rk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb9z0es%2FbtrLkaKpeo4%2FAQK6zc6o5eAtoyOOumC4rk%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;2636&quot; height=&quot;528&quot; data-filename=&quot;pwa_5.png&quot; data-origin-width=&quot;2636&quot; data-origin-height=&quot;528&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;rarr; 클라우드 메시징 탭에서&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Untitled.png&quot; data-origin-width=&quot;2148&quot; data-origin-height=&quot;458&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EgyYu/btrLhXLQb1E/Y5LdKLErM2nFwCkDhO9Wf0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EgyYu/btrLhXLQb1E/Y5LdKLErM2nFwCkDhO9Wf0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EgyYu/btrLhXLQb1E/Y5LdKLErM2nFwCkDhO9Wf0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEgyYu%2FbtrLhXLQb1E%2FY5LdKLErM2nFwCkDhO9Wf0%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;2148&quot; height=&quot;458&quot; data-filename=&quot;Untitled.png&quot; data-origin-width=&quot;2148&quot; data-origin-height=&quot;458&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;웹 구성 &amp;rarr; 웹 푸시 인증서에서 받은 키 값을 넣어줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 해놓으면 기본적인 푸시 알림을 받기 위한 코드는 넣어놓은 상태입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 firebase 에서 알림을 보내거나, POST 요청으로 알림을 보낼 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;푸쉬 알람 보내는 방법&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;첫번째, POST 요청으로 보내기 ( Postman )&lt;/h3&gt;
&lt;pre class=&quot;awk&quot;&gt;&lt;code&gt;// 요청 주소
**&amp;lt;https://fcm.googleapis.com/fcm/send**&amp;gt;

// json-raw
{
		&quot;to&quot;: &quot;위에서 클라이언트측에서 받은 currentToken 값&quot;,
		&quot;notification&quot;: {
			&quot;title&quot;: &quot;test&quot;,
			&quot;body&quot;: &quot;test!&quot;
		}
	}

// header
{
	&quot;Content-Type&quot;: &quot;application/json&quot;,
	&quot;Authorization&quot;: &quot;key=서버 키&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;위에 들어가는 서버 키는 firebase 에서 google cloud 와 연결하면 나옵니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Untitled.png&quot; data-origin-width=&quot;2052&quot; data-origin-height=&quot;310&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mWKxW/btrLntWQoCH/vDyPgwIzWuIHknWciVsoSk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mWKxW/btrLntWQoCH/vDyPgwIzWuIHknWciVsoSk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mWKxW/btrLntWQoCH/vDyPgwIzWuIHknWciVsoSk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmWKxW%2FbtrLntWQoCH%2FvDyPgwIzWuIHknWciVsoSk%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;2052&quot; height=&quot;310&quot; data-filename=&quot;Untitled.png&quot; data-origin-width=&quot;2052&quot; data-origin-height=&quot;310&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 정보대로 넣어주고 요청을 보내면 푸쉬 알림이 갑니다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;pwa_6.png&quot; data-origin-width=&quot;564&quot; data-origin-height=&quot;303&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dSlEYb/btrLr1MfWmj/JMzoAiR42QixuU9AoO0Rgk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dSlEYb/btrLr1MfWmj/JMzoAiR42QixuU9AoO0Rgk/img.png&quot; data-alt=&quot;성공!&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dSlEYb/btrLr1MfWmj/JMzoAiR42QixuU9AoO0Rgk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdSlEYb%2FbtrLr1MfWmj%2FJMzoAiR42QixuU9AoO0Rgk%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;564&quot; height=&quot;303&quot; data-filename=&quot;pwa_6.png&quot; data-origin-width=&quot;564&quot; data-origin-height=&quot;303&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;성공!&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;두번째 firebase 에서 알림 보내기&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;pwa_7.png&quot; data-origin-width=&quot;504&quot; data-origin-height=&quot;1160&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cv7rkM/btrLiU8UXOC/ZXMNqb4D7LktRPbh5MvLuk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cv7rkM/btrLiU8UXOC/ZXMNqb4D7LktRPbh5MvLuk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cv7rkM/btrLiU8UXOC/ZXMNqb4D7LktRPbh5MvLuk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcv7rkM%2FbtrLiU8UXOC%2FZXMNqb4D7LktRPbh5MvLuk%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;324&quot; height=&quot;746&quot; data-filename=&quot;pwa_7.png&quot; data-origin-width=&quot;504&quot; data-origin-height=&quot;1160&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참여 / Colud Messaging ( 없다면 Messaging ) 탭을 클릭해서 들어갑니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;pwa_8.png&quot; data-origin-width=&quot;1940&quot; data-origin-height=&quot;822&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cpCDiw/btrLtMnLekK/baOCdJBCYtCKOdXZV4tQBK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cpCDiw/btrLtMnLekK/baOCdJBCYtCKOdXZV4tQBK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cpCDiw/btrLtMnLekK/baOCdJBCYtCKOdXZV4tQBK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcpCDiw%2FbtrLtMnLekK%2FbaOCdJBCYtCKOdXZV4tQBK%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;1940&quot; height=&quot;822&quot; data-filename=&quot;pwa_8.png&quot; data-origin-width=&quot;1940&quot; data-origin-height=&quot;822&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;새로운 캠페인 ( 알림 ) 을 만들어서 내용을 작성하고 테스트 메세지 전송 클릭!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;pwa_9.png&quot; data-origin-width=&quot;1234&quot; data-origin-height=&quot;464&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Fn2Cg/btrLiBhgosJ/B5TBzhPwdn74meIZjyowV0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Fn2Cg/btrLiBhgosJ/B5TBzhPwdn74meIZjyowV0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Fn2Cg/btrLiBhgosJ/B5TBzhPwdn74meIZjyowV0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFn2Cg%2FbtrLiBhgosJ%2FB5TBzhPwdn74meIZjyowV0%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;1234&quot; height=&quot;464&quot; data-filename=&quot;pwa_9.png&quot; data-origin-width=&quot;1234&quot; data-origin-height=&quot;464&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;FCM 등록 토큰 추가를 클릭하고, 아까 클라이언트에서 받은 currentToken 을 입력하고 테스트 클릭!&lt;/p&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;그러고나면 이제 해당 앱을 다운받고 알림 설정을 허용한 유저들에게 약 5 ~ 10분뒤 쯤 알림이 갑니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;pwa_10.png&quot; data-origin-width=&quot;2170&quot; data-origin-height=&quot;706&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bX19tt/btrLjj1Hr35/AI3OGLJVGrHv7kQNS1HwWk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bX19tt/btrLjj1Hr35/AI3OGLJVGrHv7kQNS1HwWk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bX19tt/btrLjj1Hr35/AI3OGLJVGrHv7kQNS1HwWk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbX19tt%2FbtrLjj1Hr35%2FAI3OGLJVGrHv7kQNS1HwWk%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;2170&quot; height=&quot;706&quot; data-filename=&quot;pwa_10.png&quot; data-origin-width=&quot;2170&quot; data-origin-height=&quot;706&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;몇개의 푸쉬 알림이 전송되었으며, 몇개가 오픈되었는지도 확인할 수 있습니다!&lt;/p&gt;</description>
      <category>웹 개발</category>
      <category>Firebase</category>
      <category>firebase server</category>
      <category>Notification</category>
      <category>pwa</category>
      <category>웹앱</category>
      <category>웹앱 푸쉬알림</category>
      <category>푸쉬 알림</category>
      <author>RPG 마니아</author>
      <guid isPermaLink="true">https://waterworkcode.tistory.com/10</guid>
      <comments>https://waterworkcode.tistory.com/entry/PWA-%ED%91%B8%EC%89%AC-%EC%95%8C%EB%A6%BC-%EB%B3%B4%EB%82%B4%EA%B8%B0#entry10comment</comments>
      <pubDate>Mon, 5 Sep 2022 12:44:47 +0900</pubDate>
    </item>
    <item>
      <title>시멘틱 태그( Sematic Tag )를 잘 사용하는 방법?</title>
      <link>https://waterworkcode.tistory.com/entry/HTML-%EA%B5%AC%EC%A1%B0%EB%A5%BC-%ED%9A%A8%EC%9C%A8%EC%A0%81%EC%9C%BC%EB%A1%9C-%EC%9E%91%EC%84%B1%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;시멘틱 태그 잘 사용하고 계신가요?&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;어떤 방식으로 시멘틱 태그를 사용하고 계신가요?&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;혹시 div 지옥처럼 section, article 지옥이 만들어지지는 않았나요?&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;HTML 구조를 더 아름답고 보기 좋게 만들 순 없을까?&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;우리가 웹개발을 시작할때 가장 먼저 만들게 되는것은 무엇일까요?&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;바로 &lt;b&gt;HTML&lt;/b&gt; 파일 일것이라고 생각합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #9d9d9d;&quot;&gt;( React, Vue 등 프레임워크를 사용한다고 해도 HTML 코드를 작성하게 될것입니다. )&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;새로운 프로젝트에게 건네는 첫인사처럼,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;새로운 마음으로 인사를 하는곳이 바로 HTML이라는 뜻입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;어떤 일이든 첫 단추가 잘 채워져야 마지막 단추도 잘 채울수 있듯이&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;HTML이 아름답게 작성 되어야 CSS, JavaScript 또한 아름답고 보기 좋게 작성 할 수 있는것 같습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;그렇다면 과연 어떻게 HTML 을 효율적으로 작성할 수 있을까요?&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Semantic Tag&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;시멘틱 태그 ( Semantic Tag )에 대해 알고 계신가요?&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;시멘틱 태그는 일반적으로 div 태그 같은 기능을 수행하지만 의미론적인 태그를 말합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;시멘틱 태그는 웹 브라우저의 크롤링 봇이 읽기 쉬운 코드이기도 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;그래서 SEO에 추가 점수를 얻는 부분이기도 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;검색엔진 최적화! 이부분만 본다고 해도 벌써부터&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;시멘틱 태그를 당장 사용해야할 것 같은 기분이 듭니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;1. 시멘틱 태그의 종류&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1661474477751&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;article&amp;gt;
&amp;lt;aside&amp;gt;
&amp;lt;details&amp;gt;
&amp;lt;figcaption&amp;gt;
&amp;lt;figure&amp;gt;
&amp;lt;footer&amp;gt;
&amp;lt;header&amp;gt;
&amp;lt;main&amp;gt;
&amp;lt;mark&amp;gt;
&amp;lt;nav&amp;gt;
&amp;lt;section&amp;gt;
&amp;lt;summary&amp;gt;
&amp;lt;time&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;2. 시멘틱 태그의 구성&lt;/b&gt;&lt;/span&gt;&lt;/h4&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;486&quot; data-origin-height=&quot;560&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vRkNx/btrKlU3phxn/T5bx8cADSBOzeGMmSGZLq1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vRkNx/btrKlU3phxn/T5bx8cADSBOzeGMmSGZLq1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vRkNx/btrKlU3phxn/T5bx8cADSBOzeGMmSGZLq1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvRkNx%2FbtrKlU3phxn%2FT5bx8cADSBOzeGMmSGZLq1%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; alt=&quot;출처 : https://www.w3schools.com/html/html5_semantic_elements.asp&quot; loading=&quot;lazy&quot; width=&quot;486&quot; height=&quot;560&quot; data-origin-width=&quot;486&quot; data-origin-height=&quot;560&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;위 사진처럼 시멘틱 태그를 사용하면,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;해당 태그가 어떤 역할을 하는 태그인지 한눈에 알아보기 쉽습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1661301328875&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;header&amp;gt;&amp;lt;/header&amp;gt;
&amp;lt;!-- 위 태그는 누가봐도 헤더입니다. --&amp;gt;

&amp;lt;nav&amp;gt;&amp;lt;/nav&amp;gt;
&amp;lt;!-- 위 태그는 누가봐도 네비게이션 입니다. --&amp;gt;

&amp;lt;footer&amp;gt;&amp;lt;/footer&amp;gt;
&amp;lt;!-- 위 태그는 누가봐도 푸터입니다. --&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;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;꼭 사진처럼 왼쪽에 네비를 둘 필요는 없고 aside를 사용하지 않을 수도 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;태그의 전체적인 레이아웃을 잡을때 시멘틱 태그를 사용하면 좋습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;하지만 무분별한 시멘틱 태그의 사용은 구조를 복잡하게 만들것이고,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt; 시멘틱 태그의 본질을 잃어버리게 만들것 입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;3. 어떻게 사용해야 할까?&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;의도에 맞지 않게 무분별하게 사용하게 된다면 오히려 혼란만 가중이 될것 같다고 생각이 듭니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;애초에 Sematic Tag 이란 의미론적인 태그입니다.&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;lt;header&amp;gt; : &lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;소개 콘텐츠 또는 탐색 링크가 들어가는 컨테이너&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;&lt;span&gt;&amp;lt;article&amp;gt;&amp;nbsp; : 독립적 / 자체 콘텐츠가 포함된 컨텐츠&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;&lt;span&gt;&amp;lt;section&amp;gt; : 제목이 있는 주제별 콘텐츠 그룹&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;lt;footer&amp;gt; : 페이지의 바닥글을 정의&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위처럼 알맞는 상황에 사용하는것이 가장 좋습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;태그의 역할을 잘 알고 위치에 맞게 사용하는 것이&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt; 효율적인 HTML을 만들어낸다고 할 수 있겠군요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;그래서 시멘틱 코드만 사용하면 되나요?&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;결과적으로 이야기하면 아닙니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&quot;시멘틱 태그만 사용해라!&quot; 라는 말을 하기 위해 &lt;/span&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; letter-spacing: 0px;&quot;&gt;시멘틱 태그가 탄생된건 아니라고 생각합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;예를 들어, Navigation을 만들때 어떤식으로 만들어야 할지&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt; 구조를 한번 떠올려주시고 아래를 봐주세요&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;html xml&quot; data-ke-language=&quot;html&quot;&gt;&lt;code&gt;&amp;lt;nav&amp;gt;
  &amp;lt;div class=&quot;logo&quot;&amp;gt;
    &amp;lt;img src=&quot;logo.png&quot; /&amp;gt;
  &amp;lt;/div&amp;gt;
  &amp;lt;ul&amp;gt;
    &amp;lt;li&amp;gt;&amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt;&amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt;&amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt;&amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt;&amp;lt;/li&amp;gt;
  &amp;lt;/ul&amp;gt;
&amp;lt;/nav&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;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;여러분은 어떤 구조의 Navigation을 생각하셨나요?&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;제가 예시로 작성한 Navigation 구조와는 많이 다를수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;1. 중요한것은 과도하게 &amp;lt;div&amp;gt; 를 사용했는지?&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;2. 적재적소에 알맞게 태그를 사용했는지?&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;/span&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;3. 의도에 맞지 않는 태그를 사용했는지?&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;4. 태그의 깊이가 너무 과도하게 들어갔는지?&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;보통 위 요소들만 잘 체크한다면 아름답고 효율적인 HTML 일것이라고 생각됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;HTML 을 대충 &amp;lt;div&amp;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;그래서 결국 효율적인 HTML을 사용하는 방법이란&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;알맞은 태그를 적재적소에 맞게 사용해서 HTML 을 작성하는것이라고 생각됩니다.&lt;/p&gt;
&lt;p data-ke-size=&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;size14&quot;&gt;&lt;span style=&quot;color: #9d9d9d; font-family: 'Nanum Gothic';&quot;&gt;이 글은  저의 개인적인 생각이 많이 담겨있습니다!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #9d9d9d; font-family: 'Nanum Gothic';&quot;&gt;이미지 출처 : &lt;a href=&quot;https://www.w3schools.com/html/html5_semantic_elements.asp&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.w3schools.com/html/html5_semantic_elements.asp&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>웹 개발</category>
      <category>html</category>
      <category>HTML 잘 쓰는 방법</category>
      <category>Semantic</category>
      <category>semantic tag</category>
      <category>시멘틱</category>
      <category>효율적인</category>
      <author>RPG 마니아</author>
      <guid isPermaLink="true">https://waterworkcode.tistory.com/9</guid>
      <comments>https://waterworkcode.tistory.com/entry/HTML-%EA%B5%AC%EC%A1%B0%EB%A5%BC-%ED%9A%A8%EC%9C%A8%EC%A0%81%EC%9C%BC%EB%A1%9C-%EC%9E%91%EC%84%B1%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95#entry9comment</comments>
      <pubDate>Wed, 24 Aug 2022 09:12:05 +0900</pubDate>
    </item>
    <item>
      <title>웹 성능을 최적화하는 쉽고 간단한 방법? ( feat. 이미지 )</title>
      <link>https://waterworkcode.tistory.com/entry/%EC%9B%B9-%EC%84%B1%EB%8A%A5%EC%9D%84-%EC%B5%9C%EC%A0%81%ED%99%94%ED%95%98%EB%8A%94-%EC%89%BD%EA%B3%A0-%EA%B0%84%EB%8B%A8%ED%95%9C-%EB%B0%A9%EB%B2%95-feat-%EC%9D%B4%EB%AF%B8%EC%A7%80</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;웹사이트에서 평균적으로 용량을 가장 많이 차지하는 것은 무엇일까요?&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #8a3db6;&quot;&gt;용량을 많이 차지하는 것은 바로 이미지입니다.&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;그 뜻은 이미지의 용량을 줄이게 되면 웹 페이지 성능을 상당히 좋게 만들 수 있다는 뜻입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;일단 이미지의 용량을 줄이는 가장 빠른 방법은 이미지의 크기를 줄이는 것입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이미지의 크기를 줄이시면 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;...?&lt;/span&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;question-g633f6d802_640.jpg&quot; data-origin-width=&quot;640&quot; data-origin-height=&quot;436&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/LEZO9/btrJeruno7p/j3OhyjFYXQdjtRSsba8z60/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/LEZO9/btrJeruno7p/j3OhyjFYXQdjtRSsba8z60/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/LEZO9/btrJeruno7p/j3OhyjFYXQdjtRSsba8z60/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLEZO9%2FbtrJeruno7p%2Fj3OhyjFYXQdjtRSsba8z60%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;640&quot; height=&quot;436&quot; data-filename=&quot;question-g633f6d802_640.jpg&quot; data-origin-width=&quot;640&quot; data-origin-height=&quot;436&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;하지만 현재 이미 필요한 만큼 딱 맞춰서 넣어놓은 상태이기 때문에&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;현 상태에서 이미지의 크기를 줄이라는 것은 적절하지 못한 방법이라고 생각합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;그럼 이제 어떤 방법들을 사용해야 할까요?&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;1.&amp;nbsp; Lazy Load를 사용하기&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;첫 번째는 lazy load를 사용하는 것입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;일단 lazy load의 기본 원리는 사용자가 보고 있는 영역이 이미지가 있는 영역에 왔을 때 이미지를 로딩하는 것입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;맨 처음 사용자가 페이지에 들어왔을 때 모든 이미지를 한꺼번에 로딩하는 것이 아니라,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;그 이미지가 필요할 때 로딩하는 것이기 때문에 &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;사용자가 페이지를 처음 방문했을 때 사이트 로딩 속도가 훨씬 빨라지게 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;사용자가 보고 있는 높이 영역 : &lt;span style=&quot;color: #ee2323;&quot;&gt;0px ~ 1080px&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이미지가 있는 높이 영역 : &lt;span style=&quot;color: #ee2323;&quot;&gt;2000px ~ 2600px&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;위와 같은 상황이라고 가정했을때,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;사용자가 보고 있는 높이 영역이 2000px에 도달하게 될때 이미지를 로딩하는 방식입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;즉, 뷰포트가 이미지의 위치에 맞닿았을때 이미지를 로딩하는겁니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;사용하는 방법은 아래와 같습니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1660009812916&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;img src=&quot;https://waterworkcode.tistory.com/&quot; loading=&quot;lazy&quot; width=&quot;200&quot; height=&quot;200&quot; alt=&quot;이미지&quot; /&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이미지의 크기를 정해주어야 이미지가 로딩 되었을때의 밀림현상을 방지할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;위 방법은 Native Lazy Loading 방식입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;HTML 에서 지원하는 속성을 사용해서 넣는 방식이고 사용 방법또한 아주 쉽습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;그러나 많은 브라우저가 지원하고 있지만 지원하지 않는 브라우저 또한 존재하기 때문에&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;지원하지 않는 브라우저에서 Lazy Loading 을 적용하고 싶다면 JavaScript 를 사용해서 넣어주어야 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323; font-family: 'Nanum Gothic';&quot;&gt;하지만 &lt;span style=&quot;color: #000000;&quot;&gt;대부분 프론트엔드 코드를 작성할때 프레임워크를 많이 사용하실 겁니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323; font-family: 'Nanum Gothic';&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그 중에서도 React를 가장 많이 사용하실텐데요&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323; font-family: 'Nanum Gothic';&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;React 에서 Lazy Loading 을 쉽게 사용할 수 있게해주는 라이브러리도 있고,&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323; font-family: 'Nanum Gothic';&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Next를 사용하신다면 Next/Image 지원으로 쉽게 사용하실 수 있습니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Lazy Loading 기술은 이미지에서 적은 페이지에서 사용하기보다 &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이미지가 많은 페이지에서 사용하는것을 권장합니다 :)&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #ee2323; font-family: 'Nanum Gothic';&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2. 이미지 크기 정해주기&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323; font-family: 'Nanum Gothic';&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;두번째 방법은 이미지의 크기를 미리 정해주는것입니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이미지의 width, height 을 정해주는 것은 이미지 최적화에 도움이 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;정확히는 이미지의 크기를 정해주어 Reflow 를 방지하는 행위 입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 id=&quot;reflow&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Reflow 란?&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Action, Event을 발생시켜 요소의 크기나 위치 등을 변경하면 &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;해당 요소의 하위 / 상위 요소들을 포함하여 Layout 을 다시 그립니다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;변경하려는 특정 요소의 위치 / 크기 그리고 연관된 요소들의 위치 / 크기를 다시 계산을 하는것 입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이미지가 들어가는 부분에 크기를 정해주지 않으면 똑같은 일을 2번 해서 속도가 느려지기 때문에&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;일을 1번만 하게 해주기 위해서 크기를 정해준다고 생각하는게 쉬울것 같습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. &amp;lt;Picture&amp;gt; 태그를 이용해서 webp, avif 확장자 사용하기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;세번째 방법은 jpg, png 보다 가벼운 webp, avif 확장자의 이미지를 사용하는것 입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;png -&amp;gt; jpg -&amp;gt; webp -&amp;gt; avif&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;확장자가 바뀌면서 50배로 가벼워지는 이미지도 있고, 2배정도만 가벼워지는 이미지도 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;가끔 정말 이상하게 무거워지는 이미지도 있어서 사용하기전에 크기 한번씩 확인해주시면 더 좋을것 같습니다 :)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이미지 변환은 구글에 &quot;webp 변환&quot; 검색하시면 다양한 유료 / 무료 사이트가 나오는데 골라서 사용하시면 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;webp, avif 이미지를 &amp;lt;Picture&amp;gt; 태그를 써서 아래와 같이 사용할겁니다.&lt;/p&gt;
&lt;pre id=&quot;code_1660015646681&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;picture&amp;gt;
	&amp;lt;source srcset=&quot;./imgs//code-is-fun.avif&quot; type=&quot;image/avif&quot; /&amp;gt;
	&amp;lt;source srcset=&quot;./imgs//code-is-fun.webp&quot; type=&quot;image/webp&quot; /&amp;gt;
	&amp;lt;img src=&quot;./imgs//code-is-fun.jpg&quot; alt=&quot;code is fun!!&quot; /&amp;gt;
&amp;lt;/picture&amp;gt;

&amp;lt;!-- 
&amp;lt;picture&amp;gt;
	&amp;lt;source srcset=&quot;이미지 경로 또는 주소&quot; type=&quot;이미지 주소의 확장자&quot; /&amp;gt;
	ex) &amp;lt;source srcset=&quot;블라블라.avif&quot; type=&quot;image/avif&quot; /&amp;gt;
	&amp;lt;img src=&quot;이미지 경로 또는 주소&quot; alt=&quot;이미지 설명&quot; /&amp;gt;
&amp;lt;/picture&amp;gt;

 접속한 브라우저가 source의 타입을 지원하지 않으면 다음 source를 확인합니다.
 차근 차근 내려가면서 허용하는 타입의 source가 없으면 img 태그의 경로를 넣습니다.
 --&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 코드를 적용하면 아래처럼 나오게 됩니다.&lt;/p&gt;
&lt;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;1040&quot; data-origin-height=&quot;506&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bM6sRt/btrJk20w8JK/p6W1xpjsefLuuuDeClZ7k1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bM6sRt/btrJk20w8JK/p6W1xpjsefLuuuDeClZ7k1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bM6sRt/btrJk20w8JK/p6W1xpjsefLuuuDeClZ7k1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbM6sRt%2FbtrJk20w8JK%2Fp6W1xpjsefLuuuDeClZ7k1%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;1040&quot; height=&quot;506&quot; data-origin-width=&quot;1040&quot; data-origin-height=&quot;506&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;avif 파일이 적용된게 보이시나요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저는 크롬으로 확인을 했고, 크롬은 avif 형식의 파일을 지원하기 때문에 avif 파일을 보여주고있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 코드에서 loading=&quot;lazy&quot; 또한 넣을 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제가 변형한 파일들은 평균적으로 avif 파일이 png 파일보다 약 20배정도 가벼웠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 세가지 방법 말고도 다른 방법들이 더 존재하긴 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저는 일단 HTML 단계에서 제목처럼 쉽고 간단하게 해결 가능한 방법만 가져와 봤습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래도 저는 두번째와 세번째 방법만 적용해도 벌써 페이지가 전보다 빨라졌다는 느낌을 받았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다른 방법들을 사용하면 또 얼마나 빨라질까요...?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;페이지 최적화 쉬운단계부터 차근차근 진행해보자구요 !!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;참고 사이트 :&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/Performance/Lazy_loading&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://developer.mozilla.org/en-US/docs/Web/Performance/Lazy_loading&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1660013161301&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;Lazy loading - Web Performance | MDN&quot; data-og-description=&quot;Lazy loading is a strategy to identify resources as non-blocking (non-critical) and load these only when needed. It's a way to shorten the length of the critical rendering path, which translates into reduced page load times.&quot; data-og-host=&quot;developer.mozilla.org&quot; data-og-source-url=&quot;https://developer.mozilla.org/en-US/docs/Web/Performance/Lazy_loading&quot; data-og-url=&quot;https://developer.mozilla.org/en-US/docs/Web/Performance/Lazy_loading&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/crGerp/hyPoih60cX/WSxRHK5a8n5kCpMUKyqWhK/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/Performance/Lazy_loading&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://developer.mozilla.org/en-US/docs/Web/Performance/Lazy_loading&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/crGerp/hyPoih60cX/WSxRHK5a8n5kCpMUKyqWhK/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;Lazy loading - Web Performance | MDN&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Lazy loading is a strategy to identify resources as non-blocking (non-critical) and load these only when needed. It's a way to shorten the length of the critical rendering path, which translates into reduced page load times.&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;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;a href=&quot;http://www.tcpschool.com/html-tags/picture&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;http://www.tcpschool.com/html-tags/picture&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1660013164660&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;4차산업혁명, 코딩교육, 소프트웨어교육, 코딩기초, SW코딩, 기초코딩부터 자바 파이썬 등&quot; data-og-host=&quot;tcpschool.com&quot; data-og-source-url=&quot;http://www.tcpschool.com/html-tags/picture&quot; data-og-url=&quot;http://tcpschool.com&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/CfZN0/hyPmfUQPXe/QMVi9qc2bLWfHyjLqQlHI1/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800&quot;&gt;&lt;a href=&quot;http://www.tcpschool.com/html-tags/picture&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;http://www.tcpschool.com/html-tags/picture&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/CfZN0/hyPmfUQPXe/QMVi9qc2bLWfHyjLqQlHI1/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;코딩교육 티씨피스쿨&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;4차산업혁명, 코딩교육, 소프트웨어교육, 코딩기초, SW코딩, 기초코딩부터 자바 파이썬 등&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;tcpschool.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>웹 개발</category>
      <category>lazy loading</category>
      <category>picture</category>
      <category>seo</category>
      <category>사이트 로딩속도 개선</category>
      <category>웹사이트 최적화</category>
      <category>이미지 최적화</category>
      <category>최적화</category>
      <author>RPG 마니아</author>
      <guid isPermaLink="true">https://waterworkcode.tistory.com/8</guid>
      <comments>https://waterworkcode.tistory.com/entry/%EC%9B%B9-%EC%84%B1%EB%8A%A5%EC%9D%84-%EC%B5%9C%EC%A0%81%ED%99%94%ED%95%98%EB%8A%94-%EC%89%BD%EA%B3%A0-%EA%B0%84%EB%8B%A8%ED%95%9C-%EB%B0%A9%EB%B2%95-feat-%EC%9D%B4%EB%AF%B8%EC%A7%80#entry8comment</comments>
      <pubDate>Tue, 9 Aug 2022 12:48:47 +0900</pubDate>
    </item>
    <item>
      <title>CSS 함수 clamp를 사용해보았다.</title>
      <link>https://waterworkcode.tistory.com/entry/CSS-%ED%95%A8%EC%88%98-clamp%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%B4%EB%B3%B4%EC%95%98%EB%8B%A4</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;@media 를 사용하여 평화롭게(?) 반응형 스타일을 작업하던 어느날&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&quot;반응형을 꼭 이렇게 더럽고 귀찮게 작업해야할까...?&quot; 라는 생각이 들었습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;아주 간단한 속성하나만 추가하는데 css가 이렇게나 더러워진다니..&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&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;1396&quot; data-origin-height=&quot;230&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SL737/btrInHSeFpR/zwYmM0VgwWlgrHG040sHjK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SL737/btrInHSeFpR/zwYmM0VgwWlgrHG040sHjK/img.png&quot; data-alt=&quot;제가 위에서 더럽고 귀찮게 작업해야할까? 라고 의문이 들었던 코드입니다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SL737/btrInHSeFpR/zwYmM0VgwWlgrHG040sHjK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSL737%2FbtrInHSeFpR%2FzwYmM0VgwWlgrHG040sHjK%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;1396&quot; height=&quot;230&quot; data-origin-width=&quot;1396&quot; data-origin-height=&quot;230&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;제가 위에서 더럽고 귀찮게 작업해야할까? 라고 의문이 들었던 코드입니다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;&quot;전혀 길지도 않고 눈에 잘 들어오면서 짧은데?&quot; 라고 생각하실 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;하지만&amp;nbsp; 이런 &lt;span style=&quot;color: #000000;&quot;&gt;CSS &lt;/span&gt;코드가 점점 많아진다면요...?&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;이런 CSS 코드가 점점 많아지고 이런 파일들이 점점 많아진다면요...?&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;저는 이런 CSS 코드를 보면 CSS 코드 파악하고 수정해야하는데 읽기 싫게 너무 길다는 생각이 들것 같습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;그래서 저는 &quot;CSS에 쉽게 해주는 기능이 없을까?&quot; 생각하고 찾아보다 &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;clamp 라고 하는 CSS 함수를 찾아보게 되었습니다.&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;clamp, 일단 어떻게 사용하는걸까?&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;백문이 불여일견! &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;이해하시기 간단하게 코드로 보여드리겠습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1988&quot; data-origin-height=&quot;740&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oRP2g/btrIseaanO1/h3dmMhA2Wyl35USDaCHWck/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oRP2g/btrIseaanO1/h3dmMhA2Wyl35USDaCHWck/img.png&quot; data-alt=&quot;html 파일입니다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oRP2g/btrIseaanO1/h3dmMhA2Wyl35USDaCHWck/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoRP2g%2FbtrIseaanO1%2Fh3dmMhA2Wyl35USDaCHWck%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;1988&quot; height=&quot;740&quot; data-origin-width=&quot;1988&quot; data-origin-height=&quot;740&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;html 파일입니다.&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;1332&quot; data-origin-height=&quot;532&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rq2uu/btrInEOs9au/DosOsJyG12QIVXSyrGgOEK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rq2uu/btrInEOs9au/DosOsJyG12QIVXSyrGgOEK/img.png&quot; data-alt=&quot;clamp를 사용한 스타일 파일입니다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rq2uu/btrInEOs9au/DosOsJyG12QIVXSyrGgOEK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Frq2uu%2FbtrInEOs9au%2FDosOsJyG12QIVXSyrGgOEK%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;1332&quot; height=&quot;532&quot; data-origin-width=&quot;1332&quot; data-origin-height=&quot;532&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;clamp를 사용한 스타일 파일입니다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;위처럼 코드를 적용하면 어떤 결과가 나올까요??&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure data-ke-type=&quot;video&quot; data-ke-style=&quot;alignCenter&quot; data-video-host=&quot;kakaotv&quot; data-video-url=&quot;https://tv.kakao.com/v/430771902&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/bt5Zyp/hyPeN4zUUX/Jgdxr7zVTP9zZcny0LA4KK/img.jpg?width=2876&amp;amp;height=1374&amp;amp;face=0_0_2876_1374,https://scrap.kakaocdn.net/dn/c7w5pf/hyPeGdjrKv/h9K2JvT5ggirBw9uKxZYpK/img.jpg?width=2876&amp;amp;height=1374&amp;amp;face=0_0_2876_1374&quot; data-video-width=&quot;860&quot; data-video-height=&quot;411&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;411&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-play-service=&quot;daum_tistory&quot;&gt;&lt;iframe src=&quot;https://play-tv.kakao.com/embed/player/cliplink/430771902?service=daum_tistory&quot; width=&quot;860&quot; height=&quot;411&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;
&lt;figcaption&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;개발자도구를 보시면 요소의 크기가 최대 : 800 최소 : 300 으로 고정되는게 보이시나요?&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;한번 보셨으니 사용 방법과 설명 을 적어보자면&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1658998704253&quot; class=&quot;css&quot; data-ke-language=&quot;css&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;div {

  width: clamp(요소의 제일 작은값, 적용하고 싶은 값, 요소의 제일 큰 값);
  /*
  width: clamp(300px, 80vw, 800px);
  
  위 코드를 해석해보자면 아래와 같은 뜻입니다!
  
  80vw 로 넣을건데 (vw === Viewport Width)
  300px이하가 되면 요소가 깨져보이니까 300px 이하로는 줄어들지말고
  800px이상 커지면 그건 또 이상하니까 800px 이상으로 커지지는 말자 친구야?
  */
  
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;사용방법도 아주 간단하지 않나요??&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;그렇다면 이쯤에서 한번 원래 @media 를 사용해서 넣으려면 코드를 어떻게 짜야 했는지 한번 볼까요?&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;이미 다 아시겠지만 그래도 보여드리겠습니다  &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&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;1836&quot; data-origin-height=&quot;1170&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dZGmYk/btrIlxo4wG9/nYa9Hr0gcWI7wxvpjruFFk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dZGmYk/btrIlxo4wG9/nYa9Hr0gcWI7wxvpjruFFk/img.png&quot; data-alt=&quot;@media 를 사용한 CSS 코드&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dZGmYk/btrIlxo4wG9/nYa9Hr0gcWI7wxvpjruFFk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdZGmYk%2FbtrIlxo4wG9%2FnYa9Hr0gcWI7wxvpjruFFk%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;1836&quot; height=&quot;1170&quot; data-origin-width=&quot;1836&quot; data-origin-height=&quot;1170&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;@media 를 사용한 CSS 코드&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;위에서 clamp 를 사용한것보다 훨씬 길고 더러워보이지 않나요?&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;제가 예시로 든 코드는 실제 사용될리가 절대 없는 쓸모없는 코드이지만,&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;실제로 사용한다면 예시 코드보다 훨씬 더 간결하게 작성할 수 있을겁니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;하지만 clamp를 사용해서 @media 친구가 해주던 모든 일을 대체할 수는 없겠다라고 생각이 들었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;분명히 @media 를 사용해서만 할 수 있는일이 있을거라고 말이죠.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그래서 이번에 제가 생각하고 느낀건 이겁니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;@media 코드를 사용하지 않을 수 있는 코드는 간결하게 clamp 사용하고,&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;@media 가 꼭 필요한 부분에서만 @media 를 사용한다면 CSS코드를 보고 더 쉽고 빠르게 이해할 수 있지 않을까?&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;라고 말이죠.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그리고 이미 다른 많은 분들이 어떻게하면 반응형을&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;더 간단하면서도 이쁘게 잘 적용할 수 있을까를 많이 공부, 연구해주셨기 때문에&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;다른 많은 방법들이 존재합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;a href=&quot;https://css-tricks.com/snippets/css/fluid-typography/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Fluid Typography&lt;/a&gt; 라고 하는 CSS trick 도 존재하고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;min(), max(), % 단위와 rem 등 여러가지 수많은 방법이 존재합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt; 어떤 방법이든 아무렇게나 막 남발하며 사용하기보다는&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;사용목적에 알맞게 사용하는게 중요하다는 생각이 듭니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이미 예전에 나온 CSS 함수이긴 하지만&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이 함수를 오늘 처음 알게된 저에게는 오늘 나온 신기술과도 같으니 당장 사용해보러 가보려고 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;새로운 기술을 적용할 생각에 벌써 설레네요  &lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그럼 이만~  &lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;정보 출처 : &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/clamp&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://developer.mozilla.org/en-US/docs/Web/CSS/clamp&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1659055281855&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;clamp() - CSS: Cascading Style Sheets | MDN&quot; data-og-description=&quot;The clamp() CSS function clamps a value between an upper and lower bound. clamp() enables selecting a middle value within a range of values between a defined minimum and maximum. It takes three parameters: a minimum value, a preferred value, and a maximum &quot; data-og-host=&quot;developer.mozilla.org&quot; data-og-source-url=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/clamp&quot; data-og-url=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/clamp&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/1CrQE/hyPge0WdTw/8QM75KF1TpYSKO4YGkfkFK/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/CSS/clamp&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/clamp&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/1CrQE/hyPge0WdTw/8QM75KF1TpYSKO4YGkfkFK/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;clamp() - CSS: Cascading Style Sheets | MDN&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;The clamp() CSS function clamps a value between an upper and lower bound. clamp() enables selecting a middle value within a range of values between a defined minimum and maximum. It takes three parameters: a minimum value, a preferred value, and a maximum&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;&lt;a href=&quot;https://css-tricks.com/snippets/css/fluid-typography/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://css-tricks.com/snippets/css/fluid-typography/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1659055288881&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;Fluid Typography | CSS-Tricks&quot; data-og-description=&quot;Getting right to the code, here's a working implementation:&quot; data-og-host=&quot;css-tricks.com&quot; data-og-source-url=&quot;https://css-tricks.com/snippets/css/fluid-typography/&quot; data-og-url=&quot;https://css-tricks.com/snippets/css/fluid-typography/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/94ehS/hyPeHXZs3g/ljVe1TjSuU4KgkvzSmFXrK/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=110_406_153_452,https://scrap.kakaocdn.net/dn/dhmcIw/hyPf6V8qlM/Lw38C9rGRPeQudTaUuIYQK/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=110_406_153_452,https://scrap.kakaocdn.net/dn/tz0LQ/hyPf7AKenq/Zpwfy1d9Ce55VUaDORWRZ0/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=110_406_153_452&quot;&gt;&lt;a href=&quot;https://css-tricks.com/snippets/css/fluid-typography/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://css-tricks.com/snippets/css/fluid-typography/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/94ehS/hyPeHXZs3g/ljVe1TjSuU4KgkvzSmFXrK/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=110_406_153_452,https://scrap.kakaocdn.net/dn/dhmcIw/hyPf6V8qlM/Lw38C9rGRPeQudTaUuIYQK/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=110_406_153_452,https://scrap.kakaocdn.net/dn/tz0LQ/hyPf7AKenq/Zpwfy1d9Ce55VUaDORWRZ0/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=110_406_153_452');&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;Fluid Typography | CSS-Tricks&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Getting right to the code, here's a working implementation:&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;css-tricks.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>웹 개발</category>
      <category>CLAMP</category>
      <category>clamp()</category>
      <category>clamp란?</category>
      <category>css</category>
      <category>CSS clamp</category>
      <category>CSS function</category>
      <category>CSS 신기술</category>
      <category>CSS 함수</category>
      <category>사용기</category>
      <author>RPG 마니아</author>
      <guid isPermaLink="true">https://waterworkcode.tistory.com/7</guid>
      <comments>https://waterworkcode.tistory.com/entry/CSS-%ED%95%A8%EC%88%98-clamp%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%B4%EB%B3%B4%EC%95%98%EB%8B%A4#entry7comment</comments>
      <pubDate>Thu, 28 Jul 2022 18:07:28 +0900</pubDate>
    </item>
    <item>
      <title>React 는 왜 함수형 컴포넌트 사용을 권장할까?</title>
      <link>https://waterworkcode.tistory.com/entry/React-%EB%8A%94-%EC%99%9C-%ED%95%A8%EC%88%98%ED%98%95-%EC%BB%B4%ED%8F%AC%EB%84%8C%ED%8A%B8-%EC%82%AC%EC%9A%A9%EC%9D%84-%EA%B6%8C%EC%9E%A5%ED%95%A0%EA%B9%8C</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;React 코드를 작성하던 저는 동료에게 이런 질문을 받았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;**님 React 클래스형 컴포넌트 써보셨나요?&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;왜 함수형 컴포넌트만 쓰는건지 정확한 이유를 잘 모르겠어요&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일단 함수형 컴포넌트 작성법이 훨씬 쉽고 React 공식문서에서 권장하는 방법이니까요?&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;React를 사용하고 있으면서도 자세하게 모르고 있었던 저 자신에게 부끄러움을 느꼈습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 해당 질문으로 React 문서를 찾아보게 되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;&amp;ldquo;언제부터 이렇게 자연스럽게 함수형 컴포넌트로만 React를 사용하게 되었지?&amp;rdquo;&lt;br /&gt;&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;question-mark-g177fe3d8c_640.jpg&quot; data-origin-width=&quot;640&quot; data-origin-height=&quot;320&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ckb7Q5/btrGEK4a7o3/g5XInuhreGsg7zeSgaIAhK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ckb7Q5/btrGEK4a7o3/g5XInuhreGsg7zeSgaIAhK/img.jpg&quot; data-alt=&quot;머릿속의 수많은 물음표들&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ckb7Q5/btrGEK4a7o3/g5XInuhreGsg7zeSgaIAhK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fckb7Q5%2FbtrGEK4a7o3%2Fg5XInuhreGsg7zeSgaIAhK%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;640&quot; height=&quot;320&quot; data-filename=&quot;question-mark-g177fe3d8c_640.jpg&quot; data-origin-width=&quot;640&quot; data-origin-height=&quot;320&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;머릿속의 수많은 물음표들&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존에 Vue 2 를 사용하여 웹 개발을 하고 있었고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;회사가 사용하는 프레임워크가 변경됨으로 인해 React로 넘어왔기 때문에&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&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;빠르게 React 에 적응하고 코드를 작성해야 했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;React 공식 문서에는 함수형 컴포넌트와 클래스형 컴포넌트를 설명하는 부분이 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저는 문서의 그 부분을 더 자세히 읽어보지 않고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;React 공식 문서에서 함수형 컴포넌트 사용을 권장하고 있으니까 그거써야지 &lt;/b&gt;라는 생각으로 작성을 하다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 상황까지 오게 되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;text-align: center;&quot; data-ke-size=&quot;size23&quot;&gt;React Hook의 탄생이 함수형 컴포넌트를 권장하게 만든 가장 큰 이유이다.&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1656251578213&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;Hook의 개요 &amp;ndash; React&quot; data-og-description=&quot;A JavaScript library for building user interfaces&quot; data-og-host=&quot;ko.reactjs.org&quot; data-og-source-url=&quot;https://ko.reactjs.org/docs/hooks-intro.html&quot; data-og-url=&quot;https://ko.reactjs.org/docs/hooks-intro.html&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/elKaSc/hyOSIbLp6u/akYqw5ZaaJpu1FARyjcya1/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://ko.reactjs.org/docs/hooks-intro.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://ko.reactjs.org/docs/hooks-intro.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/elKaSc/hyOSIbLp6u/akYqw5ZaaJpu1FARyjcya1/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Hook의 개요 &amp;ndash; React&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;A JavaScript library for building user interfaces&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;ko.reactjs.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;왜 React 공식 문서에서는 함수형 컴포넌트 사용을 권장할까요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;i&gt;정확한 React의 답변은 링크된 페이지에 모두 적혀있습니다.&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일단 이유를 찾기 전에 각각 어떤식으로 작동하는지 살펴보았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;클래스형 컴포넌트는 라이프사이클( 생명주기 ), State 기능을 사용할 수 있습니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;함수형 컴포넌트는 React Hook을 사용할 수 있습니다.&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;React Hook 탄생 이전, 함수형 컴포넌트에서는 State, 라이프사이클을 사용하지 못했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 제가 그때 React 를 사용하고 있었다면 클래스형 컴포넌트를 사용했을것 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&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;클래스형 컴포넌트에 있는 라이프사이클, state 기능이 없었기 때문입니다.&lt;/p&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;React Hook 기능이 추가되면서 클래스형 컴포넌트의 단점들이 채워지게 되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;클래스형 컴포넌트의 단점&lt;/b&gt;&lt;/p&gt;
&lt;ol 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;JavaScript this 개념 때문에 혼란을 준다.&lt;/li&gt;
&lt;li&gt;코드의 최소화가 힘들다.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&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;React Hook 덕분에 클래스형 컴포넌트로 코드를 작성하지 않아도&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;React의 여러 기능을 사용할 수 있게 된겁니다!!!  &lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;결과적으로 이렇게 React 사용자들은&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;비교적 간편하고&lt;/b&gt;, &lt;b&gt;this 로 인해 혼란스럽지 않으며&lt;/b&gt;, &lt;b&gt;코드의 최소화가 쉬운&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;함수형 컴포넌트를 주로 사용하게 된것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저는 이 내용을 정리해서 해당 부분을 궁금해 했던 동료에게 바로 알려주었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;직장 동료의 궁금증 덕분에 저의 부족했던 지식을 더 채워넣게 되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;덕분에 왜 함수형 컴포넌트를 사용하는가 뿐만 아니라&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞으로 어떤것을 사용하고 어떤 코드를 작성하든 항상 &lt;b&gt;&lt;span style=&quot;color: #8a3db6;&quot;&gt;&quot;왜?&quot;&lt;/span&gt;&lt;/b&gt; 라는 질문을 달고 개발하면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;더 구체적으로 명확하게 알게 되겠구나&lt;/b&gt;&lt;/span&gt; 라고 깨닫게 되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&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;style5&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://ko.reactjs.org/docs/hooks-intro.html&quot;&gt;https://ko.reactjs.org/docs/hooks-intro.html&lt;/a&gt;&lt;/p&gt;</description>
      <category>웹 개발</category>
      <category>Functional Component</category>
      <category>lifecycle</category>
      <category>React</category>
      <category>React Hook</category>
      <category>라이프사이클</category>
      <category>리액트</category>
      <category>리액트 공부</category>
      <category>리액트 훅</category>
      <category>클래스형 컴포넌트</category>
      <category>함수형 컴포넌트</category>
      <author>RPG 마니아</author>
      <guid isPermaLink="true">https://waterworkcode.tistory.com/5</guid>
      <comments>https://waterworkcode.tistory.com/entry/React-%EB%8A%94-%EC%99%9C-%ED%95%A8%EC%88%98%ED%98%95-%EC%BB%B4%ED%8F%AC%EB%84%8C%ED%8A%B8-%EC%82%AC%EC%9A%A9%EC%9D%84-%EA%B6%8C%EC%9E%A5%ED%95%A0%EA%B9%8C#entry5comment</comments>
      <pubDate>Thu, 7 Jul 2022 10:43:53 +0900</pubDate>
    </item>
    <item>
      <title>HTTP / HTTPS 를 쉽게 알아보기로 했다.</title>
      <link>https://waterworkcode.tistory.com/entry/HTTP-HTTPS-%EB%A5%BC-%EC%95%8C%EC%95%84%EB%B3%B4%EA%B8%B0%EB%A1%9C-%ED%96%88%EB%8B%A4</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;HTTP ?&lt;/h2&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;클라이언트가 요청(request)을 보내면 서버가 요청사항에 맞는 응답(response)을 보내는 형태로 작동합니다.&lt;/p&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;176171505164CE2D12.jpeg&quot; data-origin-width=&quot;200&quot; data-origin-height=&quot;200&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bc2Wby/btrGnX3eTkE/kwGoPQqh1xgdXcILV9KPT1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bc2Wby/btrGnX3eTkE/kwGoPQqh1xgdXcILV9KPT1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bc2Wby/btrGnX3eTkE/kwGoPQqh1xgdXcILV9KPT1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbc2Wby%2FbtrGnX3eTkE%2FkwGoPQqh1xgdXcILV9KPT1%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;200&quot; height=&quot;200&quot; data-filename=&quot;176171505164CE2D12.jpeg&quot; data-origin-width=&quot;200&quot; data-origin-height=&quot;200&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;특징&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;TCP / IP 를 이용하는 응용 프로토콜 입니다. (인터넷을 통해 데이터를 주고받는 기능을 이용하는 응용 프로토콜)&lt;/li&gt;
&lt;li&gt;연결상태를 유지하지 않는 비연결성 프로토콜 입니다. (요청과 응답형태로 작동)&lt;/li&gt;
&lt;li&gt;무상태성(stateless) 프로토콜 입니다. (서버가 두 요청간에 어떠한 데이터도 유지하지 않음)&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;i&gt;TCP : 두개의 호스트를 연결하고 데이터를 교환하게 해주는 프로토콜입니다.&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;i&gt;IP : 인터넷에 연결되어 있는 장치들은 각각의 장치를 식별할 수 있는 주소를 가지고 있는데 이를 IP 라고 합니다.&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;HTTP 요청 메서드&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;GET: 특정 데이터를 받기 위한 요청입니다.&lt;/li&gt;
&lt;li&gt;POST: 데이터를 생성하거나 컨트롤러를 실행할때 사용합니다.&lt;/li&gt;
&lt;li&gt;PUT: 변경 가능한 데이터를 변경할때 사용합니다.&lt;/li&gt;
&lt;li&gt;DELETE: 특정 데이터를 삭제할때 사용합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;더 많은 메서드들이 존재하지만 주로 사용하는 메서드는 위의 4가지를 주로 사용합니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;HTTPS ?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;HTTPS는 보안 소켓 계층(SSL)을 사용하여&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;브라우저와 서버 사이에 전송된 데이터를 암호화 하여 인터넷 연결을 보안을 유지하는 표준 기술을 사용한&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;보안이 강화된 HTTP 프로토콜&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;일반적인 HTTP 통신은 통신간에 해커가 해당 요청을 중간에 훔쳐보면 모든 정보가 그대로 드러나게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;password: 게임 + 웹 개발&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위처럼 해커는 사용자의 아이디와 비밀번호를 훔쳐보고 사용자의 정보를 가져갈수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;hacker-g2743502a8_640.jpg&quot; data-origin-width=&quot;640&quot; data-origin-height=&quot;480&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bFM0bG/btrGmofTNvW/LperlPVJ6dZFpgZyvzYhn0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bFM0bG/btrGmofTNvW/LperlPVJ6dZFpgZyvzYhn0/img.jpg&quot; data-alt=&quot;http 통신중 훔쳐보는 해커&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bFM0bG/btrGmofTNvW/LperlPVJ6dZFpgZyvzYhn0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbFM0bG%2FbtrGmofTNvW%2FLperlPVJ6dZFpgZyvzYhn0%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;323&quot; height=&quot;242&quot; data-filename=&quot;hacker-g2743502a8_640.jpg&quot; data-origin-width=&quot;640&quot; data-origin-height=&quot;480&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;http 통신중 훔쳐보는 해커&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;하지만 HTTPS는&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;password: eRa12Xye&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위처럼 해커가 사용자의 요청을 훔쳐보더라도 암호화된 상태의 정보를 보게 되어&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용자의 정보를 보호할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;cyber-security-g217c717f2_640.png&quot; data-origin-width=&quot;640&quot; data-origin-height=&quot;640&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/duzB3W/btrGmn86FyQ/O5PqstVNsmMnbExLzFBFc0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/duzB3W/btrGmn86FyQ/O5PqstVNsmMnbExLzFBFc0/img.png&quot; data-alt=&quot;https 통신중 보호되는 정보&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/duzB3W/btrGmn86FyQ/O5PqstVNsmMnbExLzFBFc0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FduzB3W%2FbtrGmn86FyQ%2FO5PqstVNsmMnbExLzFBFc0%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;283&quot; height=&quot;283&quot; data-filename=&quot;cyber-security-g217c717f2_640.png&quot; data-origin-width=&quot;640&quot; data-origin-height=&quot;640&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https 통신중 보호되는 정보&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;b&gt;&lt;span style=&quot;color: #8a3db6;&quot;&gt;SEO &lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: #8a3db6;&quot;&gt;또한 높은 점수&lt;/span&gt;를 주며 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;PWA&lt;/b&gt; 또한 HTTPS 에서만 사용&lt;/span&gt;할 수 있기 때문에&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최근의 대부분의 웹 페이지는 HTTPS를 사용하는걸 지향하고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;i&gt;SEO : 검색엔진 최적화입니다. 검색 사이트에서 검색시에 상위 노출이 되기 위해서 작업합니다.&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;PWA : 프로그래시브 웹앱이라는 뜻이며, 웹과 앱의 기능 모두 이점을 가져가는 웹/앱 사이트 입니다.&lt;/span&gt;&lt;/i&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;제가 검색했던 HTTP 관련 에러 ( CORS )&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;HTTP 관련해서 주로 검색했던 에러는 CORS 에러였던것 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;HTTP 통신을 할때 해당 서버가 허용한 프로토콜, 도메인, 포트와 다를 경우 CORS 에러를 나타냅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;https://www.omg.com:8000/user&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;https://www.aomg.com:8000/user&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 예시는 도메인이 다르기 때문에 CORS 에러가 나타납니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CORS는 서버쪽 코드에서 문제를 해결해주어야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저는 Node 의 &lt;a href=&quot;https://www.npmjs.com/package/cors&quot;&gt;cors&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;&lt;a href=&quot;https://www.npmjs.com/package/cors&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.npmjs.com/package/cors&lt;/a&gt;&lt;/p&gt;</description>
      <category>웹 개발</category>
      <category>cors</category>
      <category>http</category>
      <category>HTTPS</category>
      <category>SSL</category>
      <category>보안</category>
      <author>RPG 마니아</author>
      <guid isPermaLink="true">https://waterworkcode.tistory.com/6</guid>
      <comments>https://waterworkcode.tistory.com/entry/HTTP-HTTPS-%EB%A5%BC-%EC%95%8C%EC%95%84%EB%B3%B4%EA%B8%B0%EB%A1%9C-%ED%96%88%EB%8B%A4#entry6comment</comments>
      <pubDate>Tue, 28 Jun 2022 18:29:11 +0900</pubDate>
    </item>
  </channel>
</rss>