Sveltekit

Svelte

본 문서는 2022년 4월 4일 에 작성되었습니다.

Svelte 는 프론트앤드 프레임워크로 빠른 개발, 저용량, 고성능 의 특징을 보여주는 것으로 알려져 있습니다. Velog teo - 왜 Svelte 를 좋아하나요?

이러한 Svelte 는 만들어진지 얼마 되지 않았으며, 따라서 많은 변화가 예상됩니다.
따라서, 작성일 시점의 구조 및 메서드 는 달라질 수 있을 것 같습니다.


Index

본 문서는 다음과 같이 구성했습니다.

  1. Project Setup
  2. Svelte Thoery - Bsc.
  3. Svelte Thoery - Adv.
  4. Svelte Syntax

Project Setup

1. 왜 Svelte 를 선택했나요?
2. 나는 Svelte 를 위해서 필요해요!
3. 내 이름은 Sveltekit 이에요 :)
4. 당신 CSS 는 어떻게 하실거에요?
5. 솔직히 Typescript 사용해야 하나 모르겠지만...

왜 Svelte 를 선택했나요?

뒤늦게 말하지만, 일단 저는 (Node) 신입 백앤드 개발자입니다.
그래서 백앤드와 무관한 것을 배울 때는 아래 조건이 필수였습니다.

  1. 확실한 이득을 주는가?
  2. 확실하게 재밌는가?
  3. 치명적인 단점은 없는가?

그런 점에서 볼때, React 라는 친구는 무거움 + 낮은 로딩시간의 단점이 있었습니다.
또한 많은 것들이 개발된 만큼 공부할 것의 범위와 깊이도 너무나 높다 고 느꼈습니다.

그래서 이번에는 Svelte 를 2번의 이유로 고르게 되었습니다.

나는 Svelte 를 위해서 필요해요!

Svelte 는 서버 시작 시점에 별도의 빌드업 시간 이 필요합니다.

무슨 빌드업 도구가 있을까요?
1. Babel
2. Parcel
3. Rollup
4. Snowpack

저는 그 중에서 Snowpack 을 선택했지만, 너무나 오랜 시간 끝에 포기하게 되었습니다.
다양한 이유가 있었지만 가장 큰 이유는 svelte-spa-router 이 사용이 불가했기 때문입니다.
pacakge.json 을 그대로 카피했음에도 해결하지 못하여서 약 1x 시간 투자 후 포기했습니다.

그래서 찾게 된 것은 Svelte 기반의 프레임워크 였습니다.

내 이름은 Sveltekit 이에요 :)

작성 시점에 20 시간 정도 사용해본 Sveltekit 의 장점은 다음과 같았습니다.

  1. Sveltekit 빌드 커맨드 제공
  2. Svelkekit 스켈레톤 빌드 제공
    2.1. Adaptor-auto 선택
    2.2. CSS or SCSS 선택
    2.3. Typescript 선택
  3. 놀랍도록 빠른 빌드업 시간

당신 CSS 는 어떻게 하실거에요?

일반적으로 알려진 CSS 생산성 도구는 다음으로 알고 있습니다.

  1. CSS preprocessing
  2. CSS Framework
  3. CSS in JS

1번과 3번은 손쉽게 사용할 수 있는 반면...
개인적으로 프로젝트에 적용하기 어려웠고 궁금했던 2번을 선택하기로 했습니다.

테오(teo.velog) 님께서는 AdorableCSS 등을 추천해주셨지만,
저는 TailwindCSS + HyperUI(TailwindCSS Template) 를 선택했습니다.

솔직히 Typescript 사용해야 하나 모르겠지만...

솔직히 프론트앤드에서 Typescript 를 사용해야 하는 지는 아직 모르겠습니다.
하지만 Input 태그와 Enum 을 연결해서 사용해보고 싶었기 때문에 선택하게 되었습니다.


Svelte Thoery - Bsc.

본 내용은 Svelekit 을 사용한 경험을 기반으로 작성되었습니다.

순수한 Svelte + Snowpack(etc ...) 등을 이용하지 않았기 때문에,
이러한 특징의 일부가 Svelte 와는 무관하지 않을까 라는 걱정을 하고 있습니다.

이론 부분에서는 다음을 다루고 있습니다.

  1. Router
  2. Components
  3. __layout.svelte and __layout.reset.svelte
  4. __error.svelte
  5. DOM Element ... etc
  6. Svelte/Store

Router

Express(Nest) 를 써보았다면...
Router(Module) - Controller(Controller+Service) 구조를 알 것이라고 생각합니다.

Svelte 는 어떠한 원리인지 모르겠으나 자동으로 다음과 같은 Page Route 를 해줍니다.

root/src/routes
│ ├ blog/			
│ ├ index.svelte		locahlhost:PORT/blog
│ ├ write.svelte		locahlhost:PORT/blog/wrtie
│ └ edit.svelte			locahlhost:PORT/blog/edit
├ index.svelte			locahlhost:PORT/
├ join.svelte			locahlhost:PORT/join
└ login.svelte			locahlhost:PORT/login
	// 파일명			URL 경로

Components

root/src/routes 밖에 만들어둔 svelte 는 컴포넌트 형식으로 사용할 수 있습니다.
컴포넌트 선언과 사용은 다음과 같이 할 수 있습니다.

// root/src/components/nav.svelte

<nav>
  <p> this is navigation bar </p>
</nav>
// root/src/routes/index.svelte
<script>
   import Nav from '../components/nav.svelte';
</script>

<Nav />

호출부의 변수를 Component 에 전달하는 방법?

이 때,
props 라는 방법을 사용할 수 있으며 다음과 같이 사용합니다.

// root/src/components/nav.svelte

<script>
  export let test;
</script>

<p> {test} <p>

export 는 변수를 받는 부분에서 사용하는 것이다

// root/src/routes/index.svelte
<script>
   import Nav from '../components/nav.svelte';
  let test = 'hello';
</script>

<Nav test={test} />
<nav {test} />

__layout

Svelte 에서는 __layout.svelte 를 특별한 파일로 만듭니다.

root/src/routes 하위의 __layout.svelte 는 순차적으로 호출되어,
본인이 포함하고 있는 HTML Tags 를 페이지에 넘겨줍니다.

또한 다음에 호출될 페이지의 영역은 <slot> 으로 지정됩니다.

// __layout.svelte

<h1> My name is Layout </h1>

<slot />

이러한 __layout.svelte 는 중복으로 사용될 수도 있습니다.
예를 들어, ~~/blog 의 __layout.svelte 가 있다면 다음 순서로 랜더링 됩니다.

  1. root/src/routes/__layout.svelte
  2. root/src/routes/blog/__layout.svelte

또한 __layout.reset.svelte 로 상위 레이아웃을 미적용한 상태에서 랜더링을 할 수도 있습니다.

layout 의 변수는 랜더링 후 사라진다?

  1. __layout.svelte -> page.svelte

위와 같은 경로로 변수를 전달하는 방법은 없습니다.
routes 경로 외부에 store/store.js 라는 외부 파일을
만들어서 호출하는 방식으로 사용해야 합니다.

이 때에는 svelte/store 안의 writable 과 같은 특이 객체가 사용됩니다. 자세한 내용은 SvelteS Syntax 를 참고해주세요.

__error.svelte

__error.svelte 는 에러가 발생할 경우 자동으로 연결됩니다.

// __error.svelte

<h1> Hello </h1>

[pages].svelte

[pages].svelte 의 이름으로
Parameter, Querystring 과 같은 복합 URL 을 인식할 수 있습니다.

DOM Element ... etc

아마도, 많은 분들이 스트레스 받았을 것 같습니다.

  1. 브라우저와 Node 는 다른 생태계이다.
  2. 이에 따라서, document 와 같은 객체는 Node 에는 없다.

그리고 일반적으로 html 에 직접 쓰이거나 임포트 된 코드는 document 객체 등이 사용 가능 하게 됩니다. 그 이유는 실행 시점이 유저의 접속 시점이기 때문입니다.

하지만, Svelte 는 빌드업이라는 과정으로 해당 코드가 즉시 실행 되어 버립니다.

document is not defined

즉, 위와 같은 에러 메세지가 여러분을 찾아온다는 의미입니다.

따라서, doument.querySelector 를 사용하기 위해서는 실행시점을 결정하기 위해서, 실제 HTML Tags 에 onMount 를 사용하여 호출 하는 것이 좋습니다.

Svelte/Store

SVelte 에는 Store 라는 개념이 있으며,
이를 통해서 전역 변수 와 같은 느낌으로 변수를 사용할 수 있습니다.

이 부분은 아직 사용하지 않아서 작성되지 않았습니다.

Sveltekit DOCS - $app/stores


Svelte Thoery - Adv.

Endpoint

root/src/routes/
경로 안에 생성된 pages.svelte 와 동일한 이름을 가지는 pages.js 를 만들면, 해당 부분이 Endpoint 가 될 수 있습니다.


Svelte Syntax

Variable

다음과 같이 속성을 선언할 수 있습니다.

<script>
  let data = '';
</script>

속성을 넘겨주는 것은 다음의 2가지 방법이 있습니다.

  1. svelte/store 사용
  2. props

1번은 전역적인 변수 공유의 경우이며,
2번은 Component 관계에서 사용할 수 있는 경우입니다.

<script>
  let data = 'hello';
</script>

<p>
  {data}
</p>
<input type="text" bind:value={data}/>

Class shorts

  1. 정통적인 Svelte class 부여법
  2. 약칭의 Svelte class 부여법
<!-- 정통적인 Svelte class 부여법 -->
<button
	on:click="{ () => current = 'foo' }"
	class="{current === 'foo' ? 'active' : ''}">
  This is button
</button>
<!-- 약칭의 Svelte class 부여법 -->
<button
	on:click="{() => current = 'foo'}"
	class:className="{current === 'foo'}">
  This is button
</button>

Synchronized Variables

Svelte 에서 변수는 가져다 쓰는 것 이기 때문에,
해당 변수를 받은 input 태그의 값을 변경해도 적용이 되지 않는다.

하지만, bind: 기능을 사용하면 되돌려 주는 것 이 가능해진다.

<script>
	let name = 'world';
</script>
 
<h1>
  {name}
</h1>
<input type="text" vind:value={name} />

Conditions

<script>
	let flag = true;
</script>

{#if flag}
	<h1> {flag} : yes~~~ </h1>
{:else}
	<div> {flag} : no~~~ </div>
{/if}

Loop

<script>
	let names = ['unchaptered', 'hello', 'tester'];
</script>

{#each name as names}
	<li> {name} </li>
{/each}

onMount

document.querySelector() 와 같이,
브라우저에서 작동해야 하는 함수들은 전부 onMount 라는 이벤트 핸들러를 사용해야 한다.

// 일반적인 js 방식
<script>
  import { onMount } from 'svelte';
  
  onMount(() => {
    const imageContainer = document.querySelector('#image_container');
  	imageContainer.addEventListener('click', () => console.log("hello"));
  });
</script>

단, 다음과 같은 방식으로 사용할 수도 있다.

// svelte 방식 1번
<script>
  function imageConsole() {
  	console.log("hello");
  }
</script>

<div on:click={imageConsole} />
// svelte 방식 2번
<div on:click={() => { console.log('hello'}} />

Deploy

이 파트를 작성하는 시점에는 Deploy 만 남기고 있을 것입니다.
다음을 이용하여 업로드를 진행할 수 있습니다.

  1. adapter-cloudflare
  2. adapter-netlify
  3. adapter-vercel

Ref.

  1. Svelte DOCS
  2. Sveltekit DOCS
  3. [Sveltekit 시리즈] 데이터 바인딩, 조건문, 반복문, 이벤트 핸들링
  4. Sveltekit Cloudflare

좋은 웹페이지 즐겨찾기