Foire À Questions
Autres ressources
Visitez la FÀQ de Svelte ainsi que la FÀQ de
vite-plugin-svelte
pour les
questions relatives à ces librairies.
Que puis-je construire avec SvelteKit ?
Voir la documentation concernant les types de projet pour plus d’informations.
Comment inclure des informations du fichier package.json dans mon application ?
Si vous souhaitez inclure le numéro de version de votre application ou d’autres informations
provenant du fichier package.json
au sein de votre application, vous pouvez charger le JSON de
cette manière :
import import pkg
pkg from './package.json' with { type: 'json' };
Comment corriger l’erreur qui se produit lorsque j’essaie d’ajouter un paquet ?
La plupart des erreurs qui se produisent lorsque l’on ajoute une librairie sont liées à un mauvais packaging. Vous pouvez vérifier si le packaging d’une librairie est compatible avec Node.js en entrant son nom sur le site de publint.
Voici quelques informations à avoir en tête lorsque vous vérifiez si une librairie est packagée correctement :
exports
prend la précédence sur les autres points d’entrée commemain
etmodule
. Ajouter un champexports
peut ne pas être retro-compatible puisque cela empêche les imports profonds.- Les fichiers ESM devraient avoir un nom se terminant en
.mjs
à moins que"type": "module"
ne soit précisé, auquel cas les fichiers CommonJS devraient avoir un nom se terminant en.cjs
. main
devrait être défini siexports
ne l’est pas. Il doit correspondre soit à un fichier CommonJS ou ESM et adhérer au point précédent. Si un champmodule
est défini, il doit faire référence à un fichier ESM.- Les composants Svelte devraient être distribués en tant que fichiers
.svelte
non compilés avec tout autre fichier JS du paquet écrit exclusivement en ESM. Les scripts personnalisés et les langages de style, comme TypeScript et SCSS, devraient être préprocessés en tant que JS et CSS vanille respectivement. Nous recommandons d’utilisersvelte-package
pour packager des librairies Svelte, qui se chargera de tout cela pour vous.
Les librairies fonctionnent mieux dans le navigateur avec Vite lorsqu’elles fournissent une version
ESM, particulièrement si elles sont une dépendance d’une librairie de composants Svelte. Vous
pourriez suggérer aux auteurs et autrices de librairies qu’elles fournissent une version ESM.
Toutefois, les dépendances CommonJS (CJS) devraient fonctionner quand même puisque, par défaut,
vite-plugin-svelte
va demander à Vite de les
pré-compiler
en utilisant esbuild
pour les convertir en ESM.
Si vous rencontrez toujours des problèmes, nous recommandons de chercher du côté des issues
Vite et/ou des issues de la librairie en question. Parfois
des issues peuvent être contournées en jouant avec les valeurs des options de configuration
optimizeDeps
ou
ssr
, bien que nous ne recommandions cela qu’en tant que
solution temporaire en attendant que la librairie concernée soit corrigée.
Comment utiliser l’API View Transition ?
Bien que SvelteKit n’ait pas d’intégration spécifique avec les view
transitions, vous pouvez exécuter
document.startViewTransition
dans onNavigate
pour déclencher une
transition de vue pour chaque navigation côté client.
import { function onNavigate(callback: (navigation: import("@sveltejs/kit").OnNavigate) => MaybePromise<void | (() => void)>): void
A lifecycle function that runs the supplied callback
immediately before we navigate to a new URL except during full-page navigations.
If you return a Promise
, SvelteKit will wait for it to resolve before completing the navigation. This allows you to — for example — use document.startViewTransition
. Avoid promises that are slow to resolve, since navigation will appear stalled to the user.
If a function (or a Promise
that resolves to a function) is returned from the callback, it will be called once the DOM has updated.
onNavigate
must be called during a component initialization. It remains active as long as the component is mounted.
onNavigate } from '$app/navigation';
function onNavigate(callback: (navigation: import("@sveltejs/kit").OnNavigate) => MaybePromise<void | (() => void)>): void
A lifecycle function that runs the supplied callback
immediately before we navigate to a new URL except during full-page navigations.
If you return a Promise
, SvelteKit will wait for it to resolve before completing the navigation. This allows you to — for example — use document.startViewTransition
. Avoid promises that are slow to resolve, since navigation will appear stalled to the user.
If a function (or a Promise
that resolves to a function) is returned from the callback, it will be called once the DOM has updated.
onNavigate
must be called during a component initialization. It remains active as long as the component is mounted.
onNavigate((navigation: OnNavigate
navigation) => {
if (!var document: Document
document.Document.startViewTransition(callbackOptions?: ViewTransitionUpdateCallback): ViewTransition
startViewTransition) return;
return new var Promise: PromiseConstructor
new <void | (() => void)>(executor: (resolve: (value: void | (() => void) | PromiseLike<void | (() => void)>) => void, reject: (reason?: any) => void) => void) => Promise<void | (() => void)>
Creates a new Promise.
Promise((resolve: (value: void | (() => void) | PromiseLike<void | (() => void)>) => void
resolve) => {
var document: Document
document.Document.startViewTransition(callbackOptions?: ViewTransitionUpdateCallback): ViewTransition
startViewTransition(async () => {
resolve: (value: void | (() => void) | PromiseLike<void | (() => void)>) => void
resolve();
await navigation: OnNavigate
navigation.Navigation.complete: Promise<void>
A promise that resolves once the navigation is complete, and rejects if the navigation
fails or is aborted. In the case of a willUnload
navigation, the promise will never resolve
complete;
});
});
});
Pour plus de détails, voir l’article “Unlocking view transitions” sur le blog de Svelte.
Comment mettre en place une base de données ?
Mettez le code pour requêter votre base de données dans une route de serveur —
ne requêtez pas la base de données dans des fichiers .svelte
. Vous pouvez créer un fichier db.js
ou similaire permettant de mettre en place la connexion immédiatement afin de rendre accessible le
client de base de données accessible dans votre application en tant que singleton. Vous pouvez
exécuter tout code de mise en place ne devant être exécuté qu’une seule fois dans le fichier
hooks.server.js
et importer vos utilitaires de base de données dans tout endpoint qui les
nécessiterait.
Vous pouvez utiliser le CLI de Svelte pour mettre en place des intégrations de base de données automatiquement.
Comment utiliser une librairie client qui a besoin d’accéder à document ou window ?
Si vous avez besoin d’accéder aux variables document
ou window
, ou si vous avez besoin que du
code s’exécute uniquement côté client, vous pouvez l’entourer d’une condition vérifiant la valeur de
browser
:
import { const browser: boolean
true
if the app is running in the browser.
browser } from '$app/environment';
if (const browser: boolean
true
if the app is running in the browser.
browser) {
// votre code uniquement client se place ici
}
Vous pouvez aussi exécuter du code dans onMount
si vous souhaitez qu’il soit exécuté après que le
premier composant ait été rendu dans le DOM :
import { function onMount<T>(fn: () => NotFunction<T> | Promise<NotFunction<T>> | (() => any)): void
onMount
, like $effect
, schedules a function to run as soon as the component has been mounted to the DOM.
Unlike $effect
, the provided function only runs once.
It must be called during the component’s initialisation (but doesn’t need to live inside the component;
it can be called from an external module). If a function is returned synchronously from onMount
,
it will be called when the component is unmounted.
onMount
functions do not run during server-side rendering.
onMount } from 'svelte';
onMount<void>(fn: () => void | (() => any) | Promise<void>): void
onMount
, like $effect
, schedules a function to run as soon as the component has been mounted to the DOM.
Unlike $effect
, the provided function only runs once.
It must be called during the component’s initialisation (but doesn’t need to live inside the component;
it can be called from an external module). If a function is returned synchronously from onMount
,
it will be called when the component is unmounted.
onMount
functions do not run during server-side rendering.
onMount(async () => {
const { const method: any
method } = await import('some-browser-only-library');
const method: any
method('bonjour tout le monde');
});
Si la librairie que vous souhaitez utiliser ne possède pas d’effets de bord, vous pouvez également
l’importer statiquement et elle sera supprimée (grâce au tree-shaking) du build serveur dans lequel
onMount
sera automatiquement remplacée par une opération blanche (“no-op”) :
import { function onMount<T>(fn: () => NotFunction<T> | Promise<NotFunction<T>> | (() => any)): void
onMount
, like $effect
, schedules a function to run as soon as the component has been mounted to the DOM.
Unlike $effect
, the provided function only runs once.
It must be called during the component’s initialisation (but doesn’t need to live inside the component;
it can be called from an external module). If a function is returned synchronously from onMount
,
it will be called when the component is unmounted.
onMount
functions do not run during server-side rendering.
onMount } from 'svelte';
import { module "some-browser-only-library"
method } from 'some-browser-only-library';
onMount<void>(fn: () => void | (() => any) | Promise<void>): void
onMount
, like $effect
, schedules a function to run as soon as the component has been mounted to the DOM.
Unlike $effect
, the provided function only runs once.
It must be called during the component’s initialisation (but doesn’t need to live inside the component;
it can be called from an external module). If a function is returned synchronously from onMount
,
it will be called when the component is unmounted.
onMount
functions do not run during server-side rendering.
onMount(() => {
module "some-browser-only-library"
method('bonjour tout le monde');
});
Enfin, vous pouvez également envisager d’utiliser un block {#await}
:
<script>
import { browser } from '$app/environment';
const ComponentConstructor = browser ?
import('some-browser-only-library').then((module) => module.Component) :
new Promise(() => {});
</script>
{#await ComponentConstructor}
<p>Chargement...</p>
{:then component}
<svelte:component this={component} />
{:catch error}
<p>Quelque chose s'est mal passé : {error.message}</p>
{/await}
<script lang="ts">
import { browser } from '$app/environment';
const ComponentConstructor = browser ?
import('some-browser-only-library').then((module) => module.Component) :
new Promise(() => {});
</script>
{#await ComponentConstructor}
<p>Chargement...</p>
{:then component}
<svelte:component this={component} />
{:catch error}
<p>Quelque chose s'est mal passé : {error.message}</p>
{/await}
Comment utiliser un serveur d’API différent ?
Vous pouvez utiliser event.fetch
pour requêter des données depuis
un serveur d’API externe, mais soyez conscient•e que vous aurez à gérer les
CORS, qui vont engendrer des complications
telles qu’imposer des requêtes préliminaires, ce qui augmente la latence. Les requêtes vers un
sous-domaine séparé peuvent également augmenter la latence à cause d’une recherche DNS
additionnelle, de la mise en place du TLS, etc. Si vous souhaitez utiliser cette méthode, vous
pourriez trouver la méthode handleFetch
utile.
Une autre approche est de définir un proxy pour contourner les galères de CORS. En production, vous
pourriez ré-écrire un chemin comme /api
vers le serveur d’API ; en local, utilisez l’option
server.proxy
de Vite.
La bonne manière de mettre en place des ré-écritures de chemin en production dépend généralement de votre plateforme de déploiement. Si les ré-écritures ne sont pas possibles, vous pouvez toujours ajouter une route d’API :
/** @type {import('./$types').RequestHandler} */
export function function GET({ params, url }: {
params: any;
url: any;
}): Promise<Response>
GET({ params: any
params, url: any
url }) {
return function fetch(input: string | URL | globalThis.Request, init?: RequestInit): Promise<Response> (+1 overload)
fetch(`https://my-api-server.com/${params: any
params.path + url: any
url.search}`);
}
import type { type RequestHandler = (event: Kit.RequestEvent<Record<string, any>, string | null>) => MaybePromise<Response>
type RequestHandler = (event: Kit.RequestEvent<Record<string, any>, string | null>) => MaybePromise<Response>
RequestHandler } from './$types';
export const const GET: RequestHandler
GET: type RequestHandler = (event: Kit.RequestEvent<Record<string, any>, string | null>) => MaybePromise<Response>
type RequestHandler = (event: Kit.RequestEvent<Record<string, any>, string | null>) => MaybePromise<Response>
RequestHandler = ({ params: Record<string, any>
The parameters of the current route - e.g. for a route like /blog/[slug]
, a { slug: string }
object.
params, url: URL
The requested URL.
url }) => {
return function fetch(input: string | URL | globalThis.Request, init?: RequestInit): Promise<Response> (+1 overload)
fetch(`https://my-api-server.com/${params: Record<string, any>
The parameters of the current route - e.g. for a route like /blog/[slug]
, a { slug: string }
object.
params.path + url: URL
The requested URL.
url.URL.search: string
search}`);
};
(Notez que vous pourriez également vouloir ajouter un proxy pour les requêtes POST
/ PATCH
etc.,
et relayer les en-têtes request.headers
, en fonction de vos besoins.)
Comment utiliser des middleware ?
L’adaptateur adapter-node
construit un middleware que vous pouvez utiliser avec votre propre
serveur pour le mode production. En mode dev, vous pouvez ajouter des middleware à Vite en utilisant
un plugin Vite. Par exemple :
import { module "@sveltejs/kit/vite"
sveltekit } from '@sveltejs/kit/vite';
/** @type {import('vite').Plugin} */
const const myPlugin: Plugin$1<any>
myPlugin = {
OutputPlugin.name: string
name: 'log-request-middleware',
Plugin$1<any>.configureServer?: ObjectHook<ServerHook> | undefined
Configure the vite server. The hook receives the
{@link
ViteDevServer
}
instance. This can also be used to store a reference to the server
for use in other hooks.
The hooks will be called before internal middlewares are applied. A hook
can return a post hook that will be called after internal middlewares
are applied. Hook can be async functions and will be called in series.
configureServer(server: ViteDevServer
server) {
server: ViteDevServer
server.ViteDevServer.middlewares: Connect.Server
A connect app instance.
- Can be used to attach custom middlewares to the dev server.
- Can also be used as the handler function of a custom http server
or as a middleware in any connect-style Node.js frameworks
middlewares.Connect.Server.use(fn: Connect.NextHandleFunction): Connect.Server (+3 overloads)
Utilize the given middleware handle
to the given route
,
defaulting to /. This “route” is the mount-point for the
middleware, when given a value other than / the middleware
is only effective when that segment is present in the request’s
pathname.
For example if we were to mount a function at /admin, it would
be invoked on /admin, and /admin/settings, however it would
not be invoked for /, or /posts.
use((req: Connect.IncomingMessage
req, res: ServerResponse<IncomingMessage>
res, next: Connect.NextFunction
next) => {
var console: Console
The console
module provides a simple debugging console that is similar to the
JavaScript console mechanism provided by web browsers.
The module exports two specific components:
- A
Console
class with methods such as console.log()
, console.error()
and console.warn()
that can be used to write to any Node.js stream.
- A global
console
instance configured to write to process.stdout
and
process.stderr
. The global console
can be used without importing the node:console
module.
Warning: The global console object’s methods are neither consistently
synchronous like the browser APIs they resemble, nor are they consistently
asynchronous like all other Node.js streams. See the note on process I/O
for
more information.
Example using the global console
:
console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr
Example using the Console
class:
const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err
console.Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)
Prints to stdout
with newline. Multiple arguments can be passed, with the
first used as the primary message and all additional used as substitution
values similar to printf(3)
(the arguments are all passed to util.format()
).
const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout
See util.format()
for more information.
log(`Requête reçue sur ${req: Connect.IncomingMessage
req.IncomingMessage.url?: string | undefined
Only valid for request obtained from
{@link
Server
}
.
Request URL string. This contains only the URL that is present in the actual
HTTP request. Take the following request:
GET /status?name=ryan HTTP/1.1
Accept: text/plain
To parse the URL into its parts:
new URL(`http://${process.env.HOST ?? 'localhost'}${request.url}`);
When request.url
is '/status?name=ryan'
and process.env.HOST
is undefined:
$ node
> new URL(`http://${process.env.HOST ?? 'localhost'}${request.url}`);
URL {
href: 'http://localhost/status?name=ryan',
origin: 'http://localhost',
protocol: 'http:',
username: '',
password: '',
host: 'localhost',
hostname: 'localhost',
port: '',
pathname: '/status',
search: '?name=ryan',
searchParams: URLSearchParams { 'name' => 'ryan' },
hash: ''
}
Ensure that you set process.env.HOST
to the server’s host name, or consider replacing this part entirely. If using req.headers.host
, ensure proper
validation is used, as clients may specify a custom Host
header.
url}`);
next: (err?: any) => void
next();
});
}
};
/** @type {import('vite').UserConfig} */
const const config: UserConfig
config = {
UserConfig.plugins?: PluginOption[] | undefined
Array of vite plugins to use.
plugins: [const myPlugin: Plugin$1<any>
myPlugin, module "@sveltejs/kit/vite"
sveltekit()]
};
export default const config: UserConfig
config;
Voir la documentation de Vite sur
configureServer
pour plus de détails
sur comment gérer l’ordre des middleware.
Comment utiliser Yarn ?
Est-ce que Yarn 2 est compatible ?
En quelque sorte. La fonctionalité Plug’n'Play, appelée ‘pnp’, ne fonctionnera pas (cette
fonctionnalité ne suit pas l’algorithme de résolution de modules de Node, et ne fonctionne pas
encore avec les modules JavaScript natifs, ce que
SvelteKit — ainsi qu’un nombre croissant de
paquets — utilise). Vous pouvez
utiliser nodeLinker: 'node-modules'
dans votre fichier
.yarnrc.yml
pour désactiver le pnp, mais il
sera probablement plus facile de simplement utiliser npm ou pnpm, qui est tout
aussi rapide et efficace, les problèmes de compatibilité en moins.
Comment se servir de Yarn 3 ?
Actuellement la dernière version (3) de Yarn supporte de manière expérimentale les ESM.
L’exemple ci-dessous semble fonctionner même si les résultats peuvent être différents. Créez d’abord une nouvelle application :
yarn create svelte myapp
cd myapp
Puis activez Yarn Berry :
yarn set version berry
yarn install
L’une des fonctionnalités les plus intéressantes de Yarn Berry est la possibilité d’avoir un seul
cache global pour les paquets, plutôt que d’avoir plusieurs copies sur votre disque pour chacun de
vos projets. Toutefois, définir enableGlobalCache
à true
provoque l’échec de la compilation, il
est donc recommandé d’ajouter la chose suivante au fichier .yarnrc.yml
:
nodeLinker: node-modules
Ceci va impliquer que les paquets seront téléchargés dans un dossier node_modules
local tout en
évitant le problème décrit ci-dessus, et est votre meilleure option pour utiliser la version 3 de
Yarn à l’heure actuelle.
Modifier cette page sur Github llms.txt