본 문서는 2022년 4월 4일 에 작성되었습니다.
Svelte 는 프론트앤드 프레임워크로 빠른 개발, 저용량, 고성능 의 특징을 보여주는 것으로 알려져 있습니다. Velog teo - 왜 Svelte 를 좋아하나요?
이러한 Svelte 는 만들어진지 얼마 되지 않았으며, 따라서 많은 변화가 예상됩니다.
따라서, 작성일 시점의 구조 및 메서드 는 달라질 수 있을 것 같습니다.
본 문서는 다음과 같이 구성했습니다.
1. 왜 Svelte 를 선택했나요?
2. 나는 Svelte 를 위해서 필요해요!
3. 내 이름은 Sveltekit 이에요 :)
4. 당신 CSS 는 어떻게 하실거에요?
5. 솔직히 Typescript 사용해야 하나 모르겠지만...
뒤늦게 말하지만, 일단 저는 (Node) 신입 백앤드 개발자입니다.
그래서 백앤드와 무관한 것을 배울 때는 아래 조건이 필수였습니다.
그런 점에서 볼때, React 라는 친구는 무거움 + 낮은 로딩시간의 단점이 있었습니다.
또한 많은 것들이 개발된 만큼 공부할 것의 범위와 깊이도 너무나 높다 고 느꼈습니다.
그래서 이번에는 Svelte 를 2번의 이유로 고르게 되었습니다.
Svelte 는 서버 시작 시점에 별도의 빌드업 시간 이 필요합니다.
무슨 빌드업 도구가 있을까요?
1. Babel
2. Parcel
3. Rollup
4. Snowpack
저는 그 중에서 Snowpack 을 선택했지만, 너무나 오랜 시간 끝에 포기하게 되었습니다.
다양한 이유가 있었지만 가장 큰 이유는 svelte-spa-router 이 사용이 불가했기 때문입니다.
pacakge.json 을 그대로 카피했음에도 해결하지 못하여서 약 1x 시간 투자 후 포기했습니다.
그래서 찾게 된 것은 Svelte 기반의 프레임워크 였습니다.
작성 시점에 20 시간 정도 사용해본 Sveltekit 의 장점은 다음과 같았습니다.
일반적으로 알려진 CSS 생산성 도구는 다음으로 알고 있습니다.
1번과 3번은 손쉽게 사용할 수 있는 반면...
개인적으로 프로젝트에 적용하기 어려웠고 궁금했던 2번을 선택하기로 했습니다.
테오(teo.velog) 님께서는 AdorableCSS 등을 추천해주셨지만,
저는 TailwindCSS + HyperUI(TailwindCSS Template) 를 선택했습니다.
솔직히 프론트앤드에서 Typescript 를 사용해야 하는 지는 아직 모르겠습니다.
하지만 Input 태그와 Enum 을 연결해서 사용해보고 싶었기 때문에 선택하게 되었습니다.
본 내용은 Svelekit 을 사용한 경험을 기반으로 작성되었습니다.
순수한 Svelte + Snowpack(etc ...) 등을 이용하지 않았기 때문에,
이러한 특징의 일부가 Svelte 와는 무관하지 않을까 라는 걱정을 하고 있습니다.
이론 부분에서는 다음을 다루고 있습니다.
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 경로
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} />
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 가 있다면 다음 순서로 랜더링 됩니다.
또한 __layout.reset.svelte 로 상위 레이아웃을 미적용한 상태에서 랜더링을 할 수도 있습니다.
layout 의 변수는 랜더링 후 사라진다?
- __layout.svelte -> page.svelte
위와 같은 경로로 변수를 전달하는 방법은 없습니다.
routes 경로 외부에 store/store.js 라는 외부 파일을
만들어서 호출하는 방식으로 사용해야 합니다.이 때에는 svelte/store 안의 writable 과 같은 특이 객체가 사용됩니다. 자세한 내용은 SvelteS Syntax 를 참고해주세요.
__error.svelte 는 에러가 발생할 경우 자동으로 연결됩니다.
// __error.svelte
<h1> Hello </h1>
[pages].svelte 의 이름으로
Parameter, Querystring 과 같은 복합 URL 을 인식할 수 있습니다.
아마도, 많은 분들이 스트레스 받았을 것 같습니다.
그리고 일반적으로 html 에 직접 쓰이거나 임포트 된 코드는 document 객체 등이 사용 가능 하게 됩니다. 그 이유는 실행 시점이 유저의 접속 시점이기 때문입니다.
하지만, Svelte 는 빌드업이라는 과정으로 해당 코드가 즉시 실행 되어 버립니다.
document is not defined
즉, 위와 같은 에러 메세지가 여러분을 찾아온다는 의미입니다.
따라서, doument.querySelector 를 사용하기 위해서는 실행시점을 결정하기 위해서, 실제 HTML Tags 에 onMount 를 사용하여 호출 하는 것이 좋습니다.
SVelte 에는 Store 라는 개념이 있으며,
이를 통해서 전역 변수 와 같은 느낌으로 변수를 사용할 수 있습니다.
이 부분은 아직 사용하지 않아서 작성되지 않았습니다.
root/src/routes/
경로 안에 생성된 pages.svelte 와 동일한 이름을 가지는 pages.js 를 만들면, 해당 부분이 Endpoint 가 될 수 있습니다.
다음과 같이 속성을 선언할 수 있습니다.
<script>
let data = '';
</script>
속성을 넘겨주는 것은 다음의 2가지 방법이 있습니다.
1번은 전역적인 변수 공유의 경우이며,
2번은 Component 관계에서 사용할 수 있는 경우입니다.
<script>
let data = 'hello';
</script>
<p>
{data}
</p>
<input type="text" bind:value={data}/>
<!-- 정통적인 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>
Svelte 에서 변수는 가져다 쓰는 것 이기 때문에,
해당 변수를 받은 input 태그의 값을 변경해도 적용이 되지 않는다.
하지만, bind: 기능을 사용하면 되돌려 주는 것 이 가능해진다.
<script>
let name = 'world';
</script>
<h1>
{name}
</h1>
<input type="text" vind:value={name} />
<script>
let flag = true;
</script>
{#if flag}
<h1> {flag} : yes~~~ </h1>
{:else}
<div> {flag} : no~~~ </div>
{/if}
<script>
let names = ['unchaptered', 'hello', 'tester'];
</script>
{#each name as names}
<li> {name} </li>
{/each}
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 만 남기고 있을 것입니다.
다음을 이용하여 업로드를 진행할 수 있습니다.