Earn this, Earn it.

[TIL] 기술 부채 청산하기 - 3월 둘째 주 본문

[개발 공부]

[TIL] 기술 부채 청산하기 - 3월 둘째 주

Narastro 2022. 3. 13. 11:48

Svelte편

최근에 나는 svelte로 프로젝트를 진행하면서 관련 기술에 대해 관심 있게 보는 중이다.

대세는 리액트이지만 svelte의 편리함을 한 번 느껴보고 난 이후로 리액트에 손이 잘 안 간다.

(그래서 더 위험하다... 사이드 프로젝트는 웬만하면 리액트로 하려고 하고 있다)

리액트를 공부하며 자바스크립트에 대해 더 이해하게 되는 것도 있듯이

스벨트를 공부하며 리액트에 대해 더 이해하게 되는 부분도 있는 것 같다.

그럼 이번 주에 무심코 지나갔던 부분들을 짚어보며 개념을 정리해보자.

 

bind:html로 contenteditable 수정 내용 반영하기

공식문서에도 나와있는 내용이지만,

contenteditable 특성을 줘서 HTML을 수정 가능하게 하였을 때,

이 값을 바인딩해서 처리하고 싶을 때가 있다.

예를 들어 hackMD나 노션같은 공유 편집기를 구현하고 싶을 때 유용하다.

<script>
	let html = '<p>Write some text!</p>';
</script>

<div contenteditable="true" bind:innerHTML={html}></div>

<pre>{html}</pre>

 

 

React의 useRef는 bind:this로!

리액트의 useRef처럼 상태변화를 일으키지 않으면서 해당 태그를 직접 조작하고 싶을 때가 있다.

스벨트에서는 해당 태그에서 bind:this로 변수에 연결시켜주면 된다.

<script>
	let canvas;
</script>

<canvas bind:this={canvas}
	width={32}
	height={32}
></canvas>

 

 

onMount와 afterUpdate를 통해 생명 주기에 따라 조작하자

onMount는 해당 컴포넌트가 DOM에 처음 렌더링된 후 실행되는 요소이다.

나는 위에서 canvas를 바인딩할 때 사용하였다. 

(왜냐하면 스벨트는 script가 실행되고 나서 html을 업데이트한다. 따라서 위의 예시에서 canvas 변수를 바로 조작하게 되면 undefined가 바인딩되어 있기 때문에 canvans를 조작하기 위해서는 onMount가 필수적이다.)

아래 예시 코드를 보며 이해하자.

<script>
	import { onMount } from 'svelte';

	let canvas; // 스크립트 실행 당시에는 undefined

	onMount(() => {
		실행될 함수들...
        // 여기서는 canvas가 바인딩된 상태이다.
	});
</script>

<canvas bind:this={canvas}
	width={32}
	height={32}
></canvas>

 

그렇다면 afterUpdate는 어떨 때 사용될까?

나의 경우는 오토 스크롤을 구현할 때 사용하였다.

새로운 채팅이 업데이트되었을 때마다, 스크롤을 내려주는 동작을 구현하였다.

예시로 보자.

<script>
  import { afterUpdate } from 'svelte';
  
  let el;

  const autoScroll = () => {
    if (el) el.scrollTop = el.scrollHeight;
  };

  afterUpdate(() => autoScroll()); // DOM이 업데이트 될때마다 오토 스크롤 동작
</script>

<div class="chats" bind:this={el}>
  {#each $chatStore as chat, i (i)}
    <div class="chat">{chat}</div>
  {/each}
</div>

 

스벨트킷(svelte-kit)을 사용해 개발환경을 구성해보자

스벨트킷은 리액트의 NextJS와 같은 기능을 하는 프레임워크이다.

SSR과 라우팅을 손쉽게 핸들링할 수 있게 해준다고 한다.

일단 아직 사용해보지 않아서 자세히 알지는 못하지만

간단히 개발환경을 세팅하는 방법 정도만 알고 다음 주에 적용해보면서 공부할 계획이다.

터미널에서 

npm init svelte@next 앱이름

을 입력하면 간단히 세팅할 수 있다.

(next의 경쟁자여서 next라고 @뒤에 붙는건가?)

 

 

Vite에서 환경변수 편리하게 사용하기

웹팩을 사용할 때에는 dotenv를 import해서 사용했던 기억이 있는데,

vite에서는 환경변수 앞에 VITE_를 붙여주면 바로 사용이 가능하다.

예를 들어 .env에 

VITE_ID=abc가 있을 때,

const appId = import.meta.env.VITE_ID

로 바로 불러들여 사용이 가능하다.

마찬가지로 내장 변수도 사용가능하다.

  • import.meta.env.MODE: {string} 앱이 실행 중인 모드
  • import.meta.env.BASE_URL: {string} 앱이 제공되는 기본 URL
  • import.meta.env.PROD: {boolean} 앱이 프로덕션에서 실행 중인지 여부
  • import.meta.env.DEV: {boolean} 앱이 개발 중인지 여부

다만 주의할 점은, VITE_ 접두사를 붙인 환경변수는 vite 번들링시에도 포함되므로

민감한 정보 같은 경우(DB_PASSWORD 등)에는 VITE_ 접두사를 빼고 소스 코드 외부에서 액세스할 수 있게 vite.config.js를 수정하여 사용해야된다.

왜냐하면 VITE_ 접두사를 빼면 vite 소스코드에 해당 환경 변수가 노출되지 않기 때문이다.

 

 

transition 간단하게 구현하기

svelte에서는 transition 애니메이션을 제공한다.

아래와 같이 사용하면 된다.

<script>
	import { fly } from 'svelte/transition';

	let visible = true;
</script>


<label>
	<input type="checkbox" bind:checked={visible}>
	visible
</label>

{#if visible}
	<p transition:fly="{{ y: 200, duration: 2000 }}">
		Flies in and out
	</p>
{/if}

 

 

 

 

반응형 선언을 잘 이용하자!

$: 를 붙여서 변수를 선언하면 반응형으로 선언된다.

반응형으로 선언하면 내부 변수의 값이 바뀔 때마다 해당 변수(또는 함수)가 매번 실행된다.

리액트의 useEffect랑 비슷하다.

useEffect에서는 두 번째 파라미터로 관찰할 요소를 지정해준다면,

svelte에서는 내부의 변수를 자동으로 관찰한다.

아래 예시를 보자.

<script>
	export let num;

	$: squared = num * num; // num값이 변경될 때마다 실행됨
</script>

 

 

 

애니메이션편

최근 진행중인 프로젝트에서는 sprite를 이용하여 애니메이션을 구현하고 있다.

이에 대해서 개념을 정리해볼까 한다.

 

sprite란?

이미지 스프라이트란 여러 개의 이미지를 하나의 이미지로 합쳐서 관리하는 이미지를 말한다.

웹앱에서 이미지가 사용될 경우 해당 이미지 다운로드를 위해 서버에 이미지를 요청하게 되는데,

많은 이미지를 사용하는 애니메이션 등의 경우 이미지 요청이 빈번하게 일어나게 되고

이를 통해 요청 시간에 오버 헤드가 크게 발생하게 된다.

따라서 여러 이미지를 합친 이미지 한 번만 요청하여 그 이미지를 사용하면 

이러한 요청 시간을 단축해주는 효과를 가질 수 있다.

아래는 스프라이트 이미지 예시이다.

이미지 출처:&amp;nbsp;https://www.pngwing.com/ko/free-png-yxgdo

위와 같이 이미지를 불러와서 일부분만 짤라서 사용하면 된다.

그렇다면 이를 어떻게 구현하면 될까?

 

애니메이션을 구현함에 있어서 프로젝트에서는 크게 두 가지 방식으로 적용하였는데,

background 이미지로 넣은 후 애니메이션 효과로 프레임을 나눠서 동작하게 하는 방법과

해당 이미지를 넣은 후 애니메이션으로 translate시켜서 프레임을 나눠서 보여주는 방법이다.

아래는 예시이다.

// svg 이미지를 직접 처리하는 방법
  .walk {
    animation: walk 0.5s infinite steps(5);
  }
  @keyframes walk {
    to {
      transform: translate(calc(-190px * 5), 0px);
    }
  }
  
  
  
  // 배경 이미지로 처리하는 방법
  .limp {
    width: 190px;
    height: 190px;
    background: url('../svgs/limp.svg');
    animation: f59 1s steps(5) infinite;
  }
  @keyframes f59 {
    to {
      background-position: calc(-190px * 5);
    }
  }

 

 

새로 알게 된 용어편

오지(OG)태그?

Open Graph 태그란 메타 태그의 종류로, 

<meta property="og:url" content="http://www.helchang.com"/>
<meta property="og:type" content="website"/>
<meta property="og:title" content="헬창닷컴"/>
<meta property="og:description" content="헬창닷컴 - 헬창베스트, 대회 행사일정, 운동, 영양소, 유머"/>

이와 같이 메타태그를 넣어서 해당 웹 페이지의 링크를 공유할 때 나타나는 미리 보기를 설정할 수 있다.

(제목, 설명, 이미지, 링크, 타입 등)

 

 

requestAnimationFrame은 모니터 주사율에 따라 결정된다?!

canvas로 애니메이션을 구현할 때 rAF 함수를 쓰면 프레임에 따라 콜백을 실행시켜준다.

다만 내가 여기서 간과한 점이 있었는데, 사용자의 모니터 주사율이 다를 수 있다는 것이다.

주사율이 높은 모니터를 사용하는 사용자의 경우 콜백이 더 자주 실행되므로 클라이언트마다 다른 애니메이션이 생길 수 있다는 것이다.

물론 리플로우 전에 콜백이 실행되어 프레임을 보장할 확률이 더 높은게 rAF이지만

움직임을 일정하게 만들고 싶다면 setInterval을 쓰는게 더 좋을 수도 있겠다는 생각을 했다.

 

 

 

VDI(Virtual Desktop Infrastructure)?

VDI란 데스크탑 가상화 기술로서, 서버를 데이터센터에 두고 필요할 때 로그인해서 사용할 수 있는 가상 데스크탑 환경을 제공하는 것을 말한다. 같은 컴퓨터를 들고 다니는 것이 아니라 어떤 컴퓨터를 사용하더라도 심리스(?)하게 작업을 할 수 있다는 것을 의미한다.