SvelteKit 1.0 pre-alpha 버전에서 바뀐 점 살펴보기

December 15, 20225 minutes

안녕하세요?

오늘은 예전부터 계속 주시했었던 SvelteKit에 대해 얘기해보려고 하는데요.

SvelteKit이 드디어 2022년 12월 15일 1.0 버전이 정식 출시되었습니다.

실제 production 모드에서 사용할 수 있는 좋은 수준으로 나온 거 같은데요.

오늘은 SvelteKit에 대해 심도 있게 알아보기 전에 예전에 배웠던 분들을 위해 2022년 8월 16일 이후에 SvelteKit이 어떻게 변했는지 알아보겠습니다.


## 라우팅 문법(Routing syntax)

기존 SvelteKit 버전에서는 Next.js 12 이하나 Remix Framework처럼 파일이든 폴더든 /src/routes 폴더 밑에 있으면 라우팅이 됐었는데요.

이제는 폴더 방식만 가능합니다.

그럼 폴더 방식이란 뭘까요?

그러니까 폴더 이름이 라우팅 주소가 되고 그 안에는 index.svelte 파일이 아니라 +page.svelte 파일이 해당 라우팅을 위한 파일이 됩니다.

-- 폴더 방식 라우팅

📂 src
 📂 routes
   📜 +page.svelte
   📂 about
    📜 +page.svelte
   📂 blog
     📜 +page.svelte
     📂 post-title
       📜 +page.md

.md 파일 확장자는 extension을 설치하면 가능합니다.

뭔가 플러스(+) 글자를 page.svelte에 붙인다는 게 이상해 보입니다.

그런데 플러스(+) 글자를 추가하면서 (+) 글자가 없는 파일은 라우팅으로 계산 안되게 끔 하는 깔끔하고 간단한 방법도 제공해주니까 한편으론 좀 더 이해하기가 쉬워졌다고 할까요?

그래서 실제 SvelteKit에서는 개인적인 파일 이름에 (+) 글자를 붙일 수 없습니다.

즉, SvelteKit만 사용하게끔 (+) 글자가 예약되었다는 뜻입니다.


## 다이내믹 라우팅

다이내믹 라우팅은 기존과 같이 스퀘어 브래킷’[]‘을 씁니다.

📂 src
 📂 routes
   📂 blog
     📜 (a bunch of markdown files here)
     📂 [slug]
       +page.svelte

위 코드와 같이 ‘[slug]‘와 같이 다이내믹 라우팅을 지정하면 SvelteKit은 ‘[slug]‘폴더의 +page.svelte 파일의 load 함수를 찾습니다.

여기 load 함수에서 해당 다이내믹 처리를 해줘야 합니다.


## Layouts

기존 버전에서는 레이아웃 파일에는 언더스코프 두개(__)를 썼었는데요.

새로운 버전에서는 그냥 +layout.svelte라고 씁니다.

-- 레이아웃 새로운 규칙

📂 src
 📂 routes
   📜 +layout.svelte

참고로 __error.svelte도 +error.svelte로 바뀌었습니다.


## 라우팅 폴더에 숨긴 파일은?

기존 버전에서는 “src/routes” 폴더 밑에 언더스코프(_) 한 개를 파일 이름 앞에 붙이면 그 파일은 라우팅 예외가 됐었는데요.

이제부터는 (+) 글자 규칙을 따르기 때문에 (+) 글자가 없는 파일은 자동으로 라우팅에 제외됩니다.


## load 함수

예전 버전에서 load 함수를 사용하려면 script 태그를 따로 또 만들어야 했는데요.

<!-- Old load function -->
<script context="module">
export const load = () => {
  // Do stuff here
  return {
    props: {
      // The stuff to return
    }
  }
}
</script>

<script>
// Normal Svelte component stuff here
</script>

새로운 버전에서는 위와 같이 쓸 필요가 없어졌습니다.

+page.js 파일이나, +page.server.js 파일 안에 그냥 선언하여 사용하시면 됩니다.

’export’ 하는 걸 잊지 마시고요.

참고로 load 함수는 서버 사이드 함수라서 +page.svelte 가 아닌 +page.js 파일 안에서 써야 합니다.

📂 src
 📂 routes
   📜 +page.svelte
   📜 +page.js 
       (or +page.server.js)

SvelteKit은 페이지를 렌더링 하기 전에 +page.js(또는 +page.server.js) 파일 안에 있는 load 함수를 먼저 호출합니다.

Remix Framework의 loader 함수와 그 사용법이 같다고 볼 수 있습니다.

참고로 load 함수의 조건입니다.

  1. load 함수는 export 되어야 한다.

  2. load 함수는 url, params 파라미터를 가진다.

  3. load 함수는 무조건 객체(빈 객체도 가능)를 리턴해야 한다. +page.svelte 파일에 prop으로 리턴됩니다.

참고로 load 함수를 모든 svelte 파일에 적용하려면 간단하게 /src/routes/+layout.svelte인 루트 레이아웃 파일에 작성하면 됩니다.


## +page.js 와 +page.server.js 차이점

+page.js 파일은 서버 사이드와 클라이언트 사이드 모두에서 작동되며,

+page.server.js 파일은 서버 사이드에서만 작동됩니다.

여기서 특히나 두 파일의 중요한 차이점을 보려면 load 함수를 예로 들어보면 쉽게 이해할 수 있습니다.

먼저, +page.js 파일에서 fetch 함수를 쓴다고 가정했을 때는 아래와 같이 하면 됩니다.

// +page.js only
import { json } from '@sveltejs/kit'

export const load = ({ fetch }) => {
  const myData = fetch('/relative/path/here')
  return json(myData)
}

실제 브라우저와 Node의 fetch는 약간 다른데요.

그래서 +page.js 파일에서는 fetch를 파라미터로 넣으면 SvelteKit이 알아서 Node 버전과 브라우저 버전의 fetch 차이를 해석하여 작동하게 되기 때문에 사용자 입장에서는 크게 걱정할 게 없습니다.

그럼 +page.server.js 파일에서 fetch는 어떻게 할까요?

+page.server.js 파일은 서버 사이드에서만 작동하기 때문에 load 함수에 파라미터로 fetch를 넣어주면 에러가 생깁니다.

그냥 아래와 같이 url을 같은 파라미터만 넘겨주고 그냥 fetch를 쓰시면 됩니다.

여기서는 Node 버전의 fetch 함수인 거죠.

// +page.server only
import { json } from '@sveltejs/kit'

export const load = ({ url }) => {
  const myData = fetch(`${url.origin}/my/api/path`)
  return json(myData)
}

## 서버 라우트(API 엔드포인트)

예전 방식의 API 엔드포인트는 아래와 같이 사용하셨겠지만,

-- 예전 endpoint structure:

📂 src
 📂 routes
   📂 api
     📜 posts.json.js

새로운 버전에서는 다음과 같이 변경되었습니다.

-- 새로운 endpoint structure:

📂 src
 📂 routes
   📂 api
     📂 posts
       📜 +server.js

위와 같이 +server.js 파일이라는 (+) 글자를 이용한 방식이며 아예 server라는 이름으로 서버 사이드만 작동된다는 파일이라고 지정했습니다.

그리고 +server.js 파일을 가지고 있는 폴더 이름을 posts에서 posts.json처럼 사용할 수 있으니 참고 바랍니다.

그리고 예전의 API 엔드포인트는 리턴되는 객체의 세팅 부분을 꼭 맞게 지정해 줘야 했는데요.

아래처럼 status와 body 부분을 지정해줘야 합니다.

// 이전 방식
export const get = () => {
  const message = 'Hello!'

  return {
    status: 200,
    body: {
      message
    }
  }
}

이제는 json 이라는 헬퍼 유틸리티도 제공하고, API 엔드포인트가 꼭 Response 객체를 리턴하게끔 바뀌었습니다.

// 새로운 방식
import { json } from '@sveltejs/kit'

export const GET = () => {
  const message = 'Hello!'
  return json(message)
}

그리고 함수 이름도, GET, POST, DELETE, PUT처럼 써야 합니다.

새로 바뀐 SvelteKit의 Respose 객체 리턴 방식이 json 헬퍼 함수를 사용하기 때문에 더 이상 status나 body를 사용하여 객체를 꾸며주지 않아도 되는데요.

만약 에러가 발생한다면 어떻게 할까요?

아래처럼 error 함수를 이용하면 됩니다.

// 예전 방식
return {
  status: 400,
  body: new Error('not found')
}

// 새로운 방식
import { error } from '@sveltejs/kit'

try {
  //return something here
}
catch({ message }) {
  throw error(400, message)
}

이상으로 SvelteKit의 메이저 변화에 대해 알아보았는데요.

다음 시간에는 SvelteKit 1.0 버전 출시를 기념해서 블로그 시스템을 만들어 보도록 하겠습니다.

그럼.