Skip to main content

Concepts avancés

Modules réservés serveur

Éditer cette page sur Github

Tel un ami proche, SvelteKit sait garder vos secrets. Lorsque vous écrivez votre code backend et votre code frontend dans le même projet, il est facile d'importer accidentellement des données sensibles dans votre code frontend (des variables d'environnement contenant des clés d'API par exemple). SvelteKit fournit un moyen de vous protéger de ce problème : les modules réservés serveur.

Variables d'environnement privées

Les modules $env/static/private et $env/dynamic/private, qui sont traités dans la section modules, peuvent uniquement être importés dans des modules qui sont exécutés sur le serveur, comme hooks.server.js ou +page.server.js.

Utilitaires côté serveur Server-only utilities

Le module $app/server, qui contient une fonction read pour lire les fichiers statiques depuis le disque, ne peut être importé que par le code serveur.

Vos modules

Vous pouvez rendre vos propres modules réservés au serveur de deux manières :

  • en ajoutant .server au nom de fichier, par ex. secrets.server.js
  • en les plaçant dans le dossier $lib/server, par ex. $lib/server/secrets.js

Comment ça marche ?

À chaque fois que du code prévu pour être affiché au public importe du code réservé au serveur (directement ou indirectement)...

$lib/server/secrets.js
ts
export const atlantisCoordinates = [/* redacted */];
Variable 'atlantisCoordinates' implicitly has an 'any[]' type.7005Variable 'atlantisCoordinates' implicitly has an 'any[]' type.
$lib/server/secrets.ts
ts
export const atlantisCoordinates = [
/* redacted */
];
src/routes/utils.js
ts
export { atlantisCoordinates } from '$lib/server/secrets.js';
Cannot find module '$lib/server/secrets.js' or its corresponding type declarations.2307Cannot find module '$lib/server/secrets.js' or its corresponding type declarations.
export const add = (a, b) => a + b;
Parameter 'a' implicitly has an 'any' type.
Parameter 'b' implicitly has an 'any' type.
7006
7006
Parameter 'a' implicitly has an 'any' type.
Parameter 'b' implicitly has an 'any' type.
src/routes/utils.ts
ts
export { atlantisCoordinates } from '$lib/server/secrets.js';
Cannot find module '$lib/server/secrets.js' or its corresponding type declarations.2307Cannot find module '$lib/server/secrets.js' or its corresponding type declarations.
export const add = (a, b) => a + b;
Parameter 'a' implicitly has an 'any' type.
Parameter 'b' implicitly has an 'any' type.
7006
7006
Parameter 'a' implicitly has an 'any' type.
Parameter 'b' implicitly has an 'any' type.
src/routes/+page.svelte
<script>
	import { add } from './utils.js';
</script>

...SvelteKit déclenche l'erreur :

Cannot import $lib/server/secrets.js into public-facing code:
- src/routes/+page.svelte
	- src/routes/utils.js
		- $lib/server/secrets.js

Même si le code affiché au public – src/routes/+page.svelte – n'utilise que l'export add et non l'export de la variable secrète atlantisCoordinates, le code secret pourrait se retrouver dans du JavaScript que le navigateur télécharge, et donc la chaîne d'import est considérée non sécurisée.

Cette fonctionnalité marche aussi avec les imports dynamiques, même ceux utilisant l'interpolation comme await import(`./${foo}.js`), avec un léger défaut : pendant le développement, s'il y a deux imports ou plus entre le code affiché au public et le module réservé au serveur, l'import illégal ne sera pas détécté la première fois que le code est chargé.

Les frameworks de test comme Vitest ne font pas la différence entre du code réservé serveur et du code affiché au public. Pour cette raison, la détection d'imports illégaux est désactivée lorsque les tests sont exécutés, c'est-à-dire quand process.env.TEST === 'true'.

Sur le même sujet

précédent Service workers
suivant Snapshots