Skip to main content

Migrer depuis Sapper

SvelteKit est le successeur de Sapper et intègre plusieurs de son design.

Si vous avez une application Sapper existante et que vous décidez de migrer vers SvelteKit, il y a un certain nombre de changements que vous avez besoin de faire. Vous pouvez vous référez à quelques exemples lors de votre migration.

package.json

type: “module”

Ajoutez "type": "module" à votre package.json. Vous pouvez faire cette étape séparément du reste en tant que migration incrémentale si vous utilisez Sapper 0.29.3 ou plus récent.

dependencies

Supprimez polka ou express, si vous utilisez l’une de ces librairies, et tout middleware comme sirv ou compression.

devDependencies

Supprimez sapper de vos devDependencies et remplacez-le par @sveltejs/kit et tout adaptateur que vous comptez utiliser (voir la prochaine section).

scripts

Tout script référençant sapper doit être mis à jour :

  • sapper build doit devenir vite build avec l’adaptateur Node
  • sapper export doit devenir vite build avec l’adaptateur statique
  • sapper dev doit devenir vite dev
  • node __sapper__/build doit devenir node build

Fichiers du projet

Le coeur de votre application, dans le dossier src/routes, peut être laissé à sa place, mais plusieurs fichiers du projet ont besoin d’être déplacés ou modifiés.

Configuration

Votre fichier webpack.config.js ou rollup.config.js doit être remplacé par un fichier svelte.config.js, comme documenté ici. Les options de préprocesseur de Svelte doivent être déplacées vers config.preprocess.

Vous devrez ajouter un adaptateur. sapper build est grossièrement équivalent à adapter-node tandis que sapper export est grossièrement équivalent à adapter-static, bien que vous puissiez préférer d’utiliser un adaptateur conçu pour la plateforme sur laquelle vous comptez déployer.

Si vous utilisiez des plugins pour des types de fichiers n’étant pas automatiquement gérés par Vite, vous devrez trouver des équivalents dans l’écosystème de Vite et les ajouter à votre configuration Vite.

src/client.js

Ce fichier n’a pas d’équivalent en SvelteKit. Toute logique personnalisée (au delà de sapper.start(...)) doit être déplacée dans votre fichier +layout.svelte, dans un callback onMount.

src/server.js

Lorsque vous utilisez l’adaptateur adapter-node, le fichier équivalent est un fichier de serveur personnalisé. Autrement, ce fichier n’a pas d’équivalent direct, puisque les applications SvelteKit peuvent être exécutées dans des environnements serverless.

src/service-worker.js

La plupart des imports effectués depuis @sapper/service-worker ont des équivalents dans $service-worker :

  • files est inchangé
  • routes a été supprimé
  • shell est maintenant build
  • timestamp est maintenant version

src/template.html

Le fichier src/template.html doit être renommé src/app.html.

Supprimez %sapper.base%, %sapper.scripts% et %sapper.styles%. Remplacez %sapper.head% par %sveltekit.head% et %sapper.html% par %sveltekit.body%. La <div id="sapper"> n’est plus nécessaire.

src/node_modules

Un pattern classique dans les applications Sapper est de mettre votre librairie interne dans un dossier à l’intérieur de src/node_modules. Ceci ne fonctionne pas avec Vite, SvelteKit utilise donc le dossier src/lib à la place.

Pages et layouts

Fichiers renommés

Les routes sont désormais constituées exclusivement du nom du dossier pour supprimer toute ambiguïté, les noms de dossier menant à un fichier +page.svelte correspondent à la route. Voir la documentation sur le routing pour un aperçu de son fonctionnement. Les exemples suivants permettent une comparaison avant/après :

Avant Après
routes/about/index.svelte routes/about/+page.svelte
routes/about.svelte routes/about/+page.svelte

Votre composant de page d’erreur personnalisée doit être renommé de _error.svelte en +error.svelte. Tout fichier _layout.svelte doit de même être renommé +layout.svelte. Tout autre fichier sera ignoré.

Imports

Les imports goto, prefetch et prefetchRoutes depuis @sapper/app doivent être remplacés par des imports goto, preloadData et preloadCode respectivement, importés depuis $app/navigation.

L’import stores depuis @sapper/app doit être remplacé — voir la section sur les Stores ci-dessous.

Tout fichier précédemment importé depuis des dossiers dans src/node_modules doit être remplacé par des imports depuis $lib.

Pré-chargement

Comme auparavant, les pages et layouts peuvent exporter une fonction qui permet aux données d’être chargées avant que le rendu ne soit exécuté.

Cette fonction a été renommé de preload en load, et doit désormais être définie dans un fichier +page.js (ou +layout.js) au même niveau du fichier +page.svelte (ou +layout.svelte) auquel il correspond, et son API a changé. Au lieu de deux arguments — page et session — il n’y a plus qu’un seul argument event.

Il n’y a plus d’objet this, et par conséquence plus de this.fetch, this.error ou this.redirect. À la place, vous pouvez obtenir fetch depuis les méthodes fournies par event et les méthodes error et redirect sont maintenant jetées automatiquement.

Stores

Avec Sapper, vous deviez récupérer les références des stores intégrés de cette manière :

import { module "@sapper/app"stores } from '@sapper/app';
const { const preloading: anypreloading, const page: anypage, const session: anysession } = module "@sapper/app"stores();

Le store page existe toujours ; preloading a été remplacé par le store navigating contenant des propriétés from et to. page a désormais des propriétés url et params, mais pas de path ou de query.

Vous pouvez accéder à ces stores de manière différentes avec SvelteKit. stores est maintenant getStores, mais dans la plupart des cas il n’est pas nécessaire de s’en servir, puisque vous pouvez importer navigating et page directement depuis $app/stores. Si vous êtes sur Svelte 5 et SvelteKit 2.12 ou plus récent, envisagez d’utiliser plutôt [$app/state].

Routing

Les routes regex ne sont plus supportées. À la place, utilisez le matching de routes avancé.

Segments

Auparavant, les composants de layout recevait une prop segment indiquant le segment enfant. Ceci a été supprimé ; vous devez utiliser la valeur plus polyvalente $page.url.pathname (ou page.url.pathname si vous utilisez Svelte 5 et SvelteKit 2.12) pour obtenir le segment qui vous intéresse.

URLs

Avec Sapper, toutes les URLs relatives étaient résolues par rapport à l’URL de base — en général /, à moins que l’option basepath ne soit utilisée — plutôt que par rapport à la page courante.

Ceci causait des problèmes et ce n’est donc plus le cas avec SvelteKit. À la place, les URLs relatives sont résolues par rapport à la page courante (ou la page de destination, pour les URLs de fetch dans les fonctions load). Dans la plupart des cas, il est plus facile d’utiliser des URLs relatives à la racine (c-à-d commençant par /), puisque leur signification n’est pas dépendant du contexte.

Attributs <a>

  • sapper:prefetch est désormais data-sveltekit-preload-data
  • sapper:noscroll est désormais data-sveltekit-noscroll

Endpoints

Avec Sapper, les routes de serveur recevaient les objets req et res exposés par le module http de Node (ou leur versions augmentées fournies par des frameworks comme Polka ou Express).

SvelteKit est conçu pour être agnostique quant à l’endroit où l’application est exécutée — elle peut être exécutée sur un serveur Node, mais tout aussi bien sur une plateforme serverless ou dans un Cloudflare Worker. Pour cette raison, vous n’interagissez plus directement avec req et res. Vos endpoints doivent être mis à jour pour correspondre à la nouvelle signature.

Pour supporter ce comportement agnostique vis-à-vis de l’environnement, fetch est désormais disponible dans le contexte global, vous n’avez donc plus besoin d’importer node-fetch, cross-fetch, ou toute autre implémentation de fetch côté serveur afin de pouvoir vous en servir.

Intégrations

Voir la section sur les intégrations pour plus d’informations sur les intégrations.

Minifacteur HTML

Sapper inclut par défaut html-minifier. SvelteKit ne l’inclut pas, mais vous pouvez l’ajouter en tant que dépendance de production et vous en servir au travers d’un hook :

import { module "html-minifier"minify } from 'html-minifier';
import { const building: boolean

SvelteKit analyses your app during the build step by running it. During this process, building is true. This also applies during prerendering.

building
} from '$app/environment';
const
const minification_options: {
    collapseBooleanAttributes: boolean;
    collapseWhitespace: boolean;
    conservativeCollapse: boolean;
    decodeEntities: boolean;
    html5: boolean;
    ignoreCustomComments: RegExp[];
    minifyCSS: boolean;
    ... 8 more ...;
    sortClassName: boolean;
}
minification_options
= {
collapseBooleanAttributes: booleancollapseBooleanAttributes: true, collapseWhitespace: booleancollapseWhitespace: true, conservativeCollapse: booleanconservativeCollapse: true, decodeEntities: booleandecodeEntities: true, html5: booleanhtml5: true, ignoreCustomComments: RegExp[]ignoreCustomComments: [/^#/], minifyCSS: booleanminifyCSS: true, minifyJS: booleanminifyJS: false, removeAttributeQuotes: booleanremoveAttributeQuotes: true, removeComments: booleanremoveComments: false, // certains codes d'hydratation nécessitent des commentaires, il faut donc les laisser removeOptionalTags: booleanremoveOptionalTags: true, removeRedundantAttributes: booleanremoveRedundantAttributes: true, removeScriptTypeAttributes: booleanremoveScriptTypeAttributes: true, removeStyleLinkTypeAttributes: booleanremoveStyleLinkTypeAttributes: true, sortAttributes: booleansortAttributes: true, sortClassName: booleansortClassName: true }; /** @type {import('@sveltejs/kit').Handle} */ export async function
function handle(input: {
    event: RequestEvent;
    resolve: (event: RequestEvent, opts?: ResolveOptions) => MaybePromise<Response>;
}): MaybePromise<...>
@type{import('@sveltejs/kit').Handle}
handle
({ event: RequestEvent<Partial<Record<string, string>>, string | null>event, resolve: (event: RequestEvent, opts?: ResolveOptions) => MaybePromise<Response>resolve }) {
let let page: stringpage = ''; return resolve: (event: RequestEvent, opts?: ResolveOptions) => MaybePromise<Response>resolve(event: RequestEvent<Partial<Record<string, string>>, string | null>event, {
ResolveOptions.transformPageChunk?: ((input: {
    html: string;
    done: boolean;
}) => MaybePromise<string | undefined>) | undefined

Applies custom transforms to HTML. If done is true, it’s the final chunk. Chunks are not guaranteed to be well-formed HTML (they could include an element’s opening tag but not its closing tag, for example) but they will always be split at sensible boundaries such as %sveltekit.head% or layout/page components.

@paraminput the html chunk and the info if this is the last chunk
transformPageChunk
: ({ html: stringhtml, done: booleandone }) => {
let page: stringpage += html: stringhtml; if (done: booleandone) { return const building: boolean

SvelteKit analyses your app during the build step by running it. During this process, building is true. This also applies during prerendering.

building
? module "html-minifier"minify(let page: stringpage,
const minification_options: {
    collapseBooleanAttributes: boolean;
    collapseWhitespace: boolean;
    conservativeCollapse: boolean;
    decodeEntities: boolean;
    html5: boolean;
    ignoreCustomComments: RegExp[];
    minifyCSS: boolean;
    ... 8 more ...;
    sortClassName: boolean;
}
minification_options
) : let page: stringpage;
} } }); }

Notez que prerendering vaut false lorsque vous utilisez vite preview pour tester le build de production du site, donc pour vérifier le résultat de la minification, vous devrez inspecter les fichiers HTML compilés directement.

Modifier cette page sur Github llms.txt