Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simple notes from Migrating to PlusKit #92

Closed
swyxio opened this issue Aug 19, 2022 · 6 comments
Closed

Simple notes from Migrating to PlusKit #92

swyxio opened this issue Aug 19, 2022 · 6 comments

Comments

@swyxio
Copy link
Owner

swyxio commented Aug 19, 2022


cover_image: https://user-images.githubusercontent.com/6764957/185548551-cdbe7da1-a15f-43dd-9c8c-4aa10a15d1ef.png
tags: svelte, sveltekit, changelog

"PlusKit" is my affectionate name for the Great SvelteKit Redesign of 2022. I was a little apprehensive at the amount of work and learning curve there would be, but it took about 1 hour all told (for admittedly a very simple sveltekit app like swyxkit).

You can see the final PR here: #88

What follows are just raw notes for "simple" sveltekit users like me. I want to stress that this is an incomplete list - however, I guess that if a "simple" usecase required these refactors, then they are the essential ones that most people will run into.

Run the migrate script

npx svelte-migrate routes

image

This is pretty straightforward - the migration script moves your code around and sometimes indiscriminately - in some cases you may have to move back some code (by uncommenting it back in) and in others you may have to refactor return signatures and imports. I found all the @migration hints to give enough warning - I solely looked at the @migration hints and that was sufficient.

image

Follow the instructions, but you'll want to upgrade your sveltekit version as well: npm i @sveltejs/kit@1.0.0-next.423.

The 4 kinds of refactors

Static imports

Since we no longer have <script context="module">, if you did some static imports in a layout/page component, you'll need to just move that into a <script>:

// src/routes/__layout.svelte -> src/routes/+layout.svelte
- <script context="module">
-  	import { MY_TWITTER_HANDLE, MY_YOUTUBE, REPO_URL, SITE_TITLE } from '$lib/siteConfig';
- </script>

<script>
	import '../tailwind.css';
	import Nav from '../components/Nav.svelte';
+ 	import { MY_TWITTER_HANDLE, MY_YOUTUBE, REPO_URL, SITE_TITLE } from '$lib/siteConfig';
</script>

This was fairly easy.

Special page values

Now that we don't have load() in a page, we dont have access to url, status, or error from load(). Pull them from the page store instead:

// src/routes/__error.svelte -> src/routes/+error.svelte
- <script context="module">
- 	/** @type {import('@sveltejs/kit').ErrorLoad} */
- 	export function load({ url, error, status }) {
- 		return {
- 			props: { error, status, url }
- 		};
- 	}
- </script>

<script>
-	export let url;
-	export let status;
-	export let error;

+  import { page } from '$app/stores';

-	let message = offline ? 'Find the internet and try again' : error?.message;
+	let message = offline ? 'Find the internet and try again' : $page.error?.message;

-	let title = offline ? 'Offline' : status;
-	if (status === 404) {
+	let title = offline ? 'Offline' : $page.status;
+	if ($page.status === 404) {
		title = 'Page not found :(';
		message = 'Sorry! If you think this URL is broken, please let me know!';
	}

</script>


-	{#if status === 404}
-		<p class="">There is no post at the slug <code>{url.pathname}</code>.</p>
-		<p><a href={'/ideas/?filter=' + url.pathname.slice(1)}>Try searching for it here!</a></p>
+	{#if $page.status === 404}
+		<p class="">There is no post at the slug <code>{$page.url.pathname}</code>.</p>
+		<p><a href={'/ideas/?filter=' + $page.url.pathname.slice(1)}>Try searching for it here!</a></p>
...

You'll want to look up what you can get from the Page store but otherwise it's also pretty straightforward.

Refactor return values

I think this took the most time for me. There a few refactors to do:

  • Refactoring error values
  • Refactoring return values and headers for pages
  • Refactoring return values and headers for API routes

See migration docs.

Refactoring Errors:

// before: page.svelte
-			if (res.status > 400) {
-				return {
-					status: res.status,
-					error: await res.text()
-				};
-			}

// after: +page.js
+ import { error } from '@sveltejs/kit';
// ...
+		if (res.status > 400) {
+			throw error(res.status, await res.text())
+		}

Refactoring return values and headers (using the new setHeaders api):

// src/routes/[slug]/+page.js
-	export async function load({ params, fetch }) {
-		    const slug = params.slug;
-		    let res = null;
-		    res = await fetch(`/api/blog/${slug}.json`);
-		    return {
-			    props: {
-				    json: await res.json(),
-				    slug,
-				    REPO_URL
-			    },
-			    cache: {
-				    maxage: 60 // 1 minute
-			    }
-		    };

+ export async function load({ params, fetch, setHeaders }) {
+		const slug = params.slug;
+		let res = null;
+		    res = await fetch(`/api/blog/${slug}.json`);
+		    setHeaders({
+			    'cache-control': 'public, max-age=60'
+		    });
+		    return {
+			      json: await res.json(),
+			      slug,
+			      REPO_URL
+		    }

This refactor looks slightly different for API routes:

// src/routes/api/blog/[slug].json
-	try {
-		data = await getContent(slug);
-		return {
-			body: JSON.stringify(data),
-			headers: {
-				'Cache-Control': `max-age=0, s-maxage=${60}` // 1 minute.. for now
-			}
-		};
-	} catch (err) {
-		return {
-			status: 404,
-			body: err.message
-		};
-	}

+ import { error } from '@sveltejs/kit';
// ...
+		data = await getContent(slug).catch(err => error(404, err.message));
+		return new Response(JSON.stringify(data), {
+			headers: {
+				'Cache-Control': `max-age=0, s-maxage=${60}`
+			}
+		});

SvelteKit has a little json helper for the new Response(JSON.stringify stuff, so the last part simplifies to:

import { error, json } from '@sveltejs/kit';
// ...
		data = await getContent(slug).catch(err => error(404, err.message));
		return json(data, {
			headers: {
				'Cache-Control': `max-age=0, s-maxage=${60}`
			}
		});

data props

Per docs, we now no longer have individual export let declarations for a +page.svelte - everything comes into export let data and the types are supposed to flow from its corresponding +page.js:

+	/** @type {import('./$types').PageData} */
+	export let data;

	/** @type {import('$lib/types').ContentItem} */
-	export let json; // warning: if you try to destructure content here, make sure to make it reactive, or your page content will not update when your user navigates
+	$: json = data.json; 

(in practice I found PageData to still be any here but I am assuming those are growing pains)

Done

There are more smaller changes to handle (I dont use stuff, I don't use session, I dont have a +page.server.js, etc), but the above was all that affected me and so I guess will be the major ones to take care of for most people, hence me writing this up. All told, about 400 lines of code affected for me.

image

Once again, you can see the final PR here: #88

@jesperordrup
Copy link

Thanks you for the notes. Good to know before starting out.

The git annotations bluish text on violent green background is hard to read. 👴

@swyxio
Copy link
Owner Author

swyxio commented Aug 19, 2022

yes i know - first time i am using the diff annotations thing so i never knew about this clash. made an issue here #93

@kevmodrome
Copy link

Nice! I'm not sure if siteConfig is something that's inherent to Swyxkit but since there's a new environment var/secrets handling functionality in SvelteKit maybe this can be deprecated? 🤔

@swyxio
Copy link
Owner Author

swyxio commented Aug 19, 2022

@kevmodrome good point, i should look into that.

@lubiah
Copy link

lubiah commented Dec 12, 2022

The colors are too bright, I mean the ones in the code tag

Copy link
Owner Author

swyxio commented Jan 15, 2023

@kudadam agree, i just lowered the opacity #160

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants