[examples] Update SvelteKit example with latest boilerplate (#7892)

Replaces https://github.com/vercel/vercel/pull/7674 with the latest SvelteKit boilerplate.
This commit is contained in:
Lee Robinson
2022-05-30 02:57:46 -05:00
committed by GitHub
parent b07ff7431f
commit c414288b2f
22 changed files with 2362 additions and 1900 deletions

View File

@@ -7,3 +7,4 @@ node_modules
.env.*
!.env.example
.vercel
.output

View File

@@ -0,0 +1,13 @@
.DS_Store
node_modules
/build
/.svelte-kit
/package
.env
.env.*
!.env.example
# Ignore files for PNPM, NPM and YARN
pnpm-lock.yaml
package-lock.json
yarn.lock

View File

@@ -0,0 +1,6 @@
{
"useTabs": false,
"singleQuote": true,
"trailingComma": "none",
"printWidth": 100
}

View File

@@ -14,31 +14,29 @@ If you're seeing this, you've probably already done this step. Congrats!
```bash
# create a new project in the current directory
npm init svelte@next
npm init svelte
# create a new project in my-app
npm init svelte@next my-app
npm init svelte my-app
```
> Note: the `@next` is temporary
## Developing
Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server:
Once you've created a project and installed dependencies with `pnpm install`, start a development server:
```bash
npm run dev
pnpm run dev
# or start the server and open the app in a new browser tab
npm run dev -- --open
pnpm run dev -- --open
```
## Building
This uses the adapter-auto for SvelteKit, which detects Vercel and runs adapter-vercel on your behalf.
To create a production version of your app:
```bash
npm run build
pnpm run build
```
> You can preview the built app with `npm run preview`, regardless of whether you installed an adapter. This should _not_ be used to serve your app in production.
You can preview the production build with `npm run preview`.

View File

@@ -1,10 +1,13 @@
{
"extends": "./.svelte-kit/tsconfig.json",
"compilerOptions": {
"baseUrl": ".",
"paths": {
"$lib": ["src/lib"],
"$lib/*": ["src/lib/*"]
"allowJs": true,
"checkJs": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"sourceMap": true,
"strict": true
}
},
"include": ["src/**/*.d.ts", "src/**/*.js", "src/**/*.svelte"]
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,22 +1,29 @@
{
"private": true,
"name": "sveltekit",
"version": "0.0.1",
"scripts": {
"dev": "svelte-kit dev",
"build": "svelte-kit build",
"package": "svelte-kit package",
"preview": "svelte-kit preview"
"preview": "svelte-kit preview",
"prepare": "svelte-kit sync",
"check": "svelte-check --tsconfig ./jsconfig.json",
"check:watch": "svelte-check --tsconfig ./jsconfig.json --watch",
"lint": "prettier --check --plugin-search-dir=. .",
"format": "prettier --write --plugin-search-dir=. ."
},
"devDependencies": {
"@sveltejs/adapter-auto": "next",
"@sveltejs/kit": "next",
"svelte": "^3.46.0"
"@types/cookie": "^0.4.1",
"prettier": "^2.5.1",
"prettier-plugin-svelte": "^2.5.0",
"svelte": "^3.46.0",
"svelte-check": "^2.2.6",
"typescript": "~4.6.2"
},
"type": "module",
"dependencies": {
"@fontsource/fira-mono": "^4.5.0",
"@lukeed/uuid": "^2.0.0",
"cookie": "^0.4.1"
}
}

1633
examples/sveltekit/pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load Diff

15
examples/sveltekit/src/app.d.ts vendored Normal file
View File

@@ -0,0 +1,15 @@
/// <reference types="@sveltejs/kit" />
// See https://kit.svelte.dev/docs/types#app
// for information about these interfaces
declare namespace App {
interface Locals {
userid: string;
}
// interface Platform {}
// interface Session {}
// interface Stuff {}
}

View File

@@ -2,12 +2,11 @@
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="description" content="Svelte demo app" />
<link rel="icon" href="%svelte.assets%/favicon.png" />
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
%svelte.head%
%sveltekit.head%
</head>
<body>
<div>%svelte.body%</div>
<div>%sveltekit.body%</div>
</body>
</html>

View File

@@ -1,13 +1,13 @@
import cookie from 'cookie';
import { v4 as uuid } from '@lukeed/uuid';
import * as cookie from 'cookie';
/** @type {import('@sveltejs/kit').Handle} */
export const handle = async ({ event, resolve }) => {
const cookies = cookie.parse(event.request.headers.get('cookie') || '');
event.locals.userid = cookies.userid || uuid();
event.locals.userid = cookies['userid'] || crypto.randomUUID();
const response = await resolve(event);
if (!cookies.userid) {
if (!cookies['userid']) {
// if this is the first time the user has visited this app,
// set a cookie so that we recognise them when they return
response.headers.set(

View File

@@ -7,6 +7,10 @@
$: displayed_count.set(count);
$: offset = modulo($displayed_count, 1);
/**
* @param {number} n
* @param {number} m
*/
function modulo(n, m) {
// handle negative numbers
return ((n % m) + m) % m;
@@ -50,6 +54,7 @@
justify-content: center;
border: 0;
background-color: transparent;
touch-action: manipulation;
color: var(--text-color);
font-size: 2rem;
}

View File

@@ -2,9 +2,36 @@ import { invalidate } from '$app/navigation';
// this action (https://svelte.dev/tutorial/actions) allows us to
// progressively enhance a <form> that already works without JS
/**
* @param {HTMLFormElement} form
* @param {{
* pending?: ({ data, form }: { data: FormData; form: HTMLFormElement }) => void;
* error?: ({
* data,
* form,
* response,
* error
* }: {
* data: FormData;
* form: HTMLFormElement;
* response: Response | null;
* error: Error | null;
* }) => void;
* result?: ({
* data,
* form,
* response
* }: {
* data: FormData;
* response: Response;
* form: HTMLFormElement;
* }) => void;
* }} [opts]
*/
export function enhance(form, { pending, error, result } = {}) {
let current_token;
/** @param {SubmitEvent} e */
async function handle_submit(e) {
const token = (current_token = {});
@@ -37,7 +64,7 @@ export function enhance(form, { pending, error, result } = {}) {
console.error(await response.text());
}
} catch (e) {
if (error) {
if (error && e instanceof Error) {
error({ data, form, error: e, response: null });
} else {
throw e;

View File

@@ -16,6 +16,7 @@
<svelte:head>
<title>About</title>
<meta name="description" content="About this app" />
</svelte:head>
<div class="content">
@@ -26,8 +27,7 @@
following into your command line and following the prompts:
</p>
<!-- TODO lose the @next! -->
<pre>npm init svelte@next</pre>
<pre>npm init svelte</pre>
<p>
The page you're looking at is purely static HTML, with no client-side interactivity needed.

View File

@@ -8,6 +8,7 @@
<svelte:head>
<title>Home</title>
<meta name="description" content="Svelte demo app" />
</svelte:head>
<section>

View File

@@ -11,6 +11,11 @@
const base = 'https://api.svelte.dev';
/**
* @param {string} method
* @param {string} resource
* @param {Record<string, unknown>} [data]
*/
export function api(method, resource, data) {
return fetch(`${base}/${resource}`, {
method,

View File

@@ -1,5 +1,6 @@
import { api } from './_api';
/** @type {import('./__types').RequestHandler} */
export const get = async ({ locals }) => {
// locals.userid comes from src/hooks.js
const response = await api('get', `todos/${locals.userid}`);
@@ -27,6 +28,7 @@ export const get = async ({ locals }) => {
};
};
/** @type {import('./index').RequestHandler} */
export const post = async ({ request, locals }) => {
const form = await request.formData();
@@ -46,6 +48,7 @@ const redirect = {
}
};
/** @type {import('./index').RequestHandler} */
export const patch = async ({ request, locals }) => {
const form = await request.formData();
@@ -57,6 +60,7 @@ export const patch = async ({ request, locals }) => {
return redirect;
};
/** @type {import('./index').RequestHandler} */
export const del = async ({ request, locals }) => {
const form = await request.formData();

View File

@@ -3,11 +3,23 @@
import { scale } from 'svelte/transition';
import { flip } from 'svelte/animate';
/**
* @typedef {{
* uid: string;
* created_at: Date;
* text: string;
* done: boolean;
* pending_delete: boolean;
* }} Todo
*/
/** @type {Todo[]} */
export let todos;
</script>
<svelte:head>
<title>Todos</title>
<meta name="description" content="A todo list app" />
</svelte:head>
<div class="todos">