Skip to main content

Serveurs Node

Pour générer un serveur Node autonome, utilisez adapter-node.

Usage

Installer le paquet avec npm i -D @sveltejs/adapter-node, puis ajoutez l’adaptateur à votre fichier svelte/config.js :

svelte.config
import import adapteradapter from '@sveltejs/adapter-node';

export default {
	
kit: {
    adapter: any;
}
kit
: {
adapter: anyadapter: import adapteradapter() } };

Déployer

D’abord, compilez votre application avec npm run build. Ceci va créer le serveur de production dans le dossier d’output défini dans les options de l’adaptateur, dont l’emplacement par défaut est build.

Vous aurez besoin du dossier d’output, du fichier package.json de votre projet, et des dépendances de production dans votre dossier node_modules pour exécuter votre application. Les dépendances de production peuvent être générées en copiant le fichier package.json et package-lock.json, puis en exécutant npm ci --omit dev (vous pouvez passer cette étape si votre application n’a aucune dépendance). Vous pouvez alors démarrer votre application avec la commande suivante :

node build

Les dépendances de développement seront empaquetées dans votre application avec Rollup. Pour contrôler si un paquet donné est inclus ou externalisé, placez-le dans devDependencies ou dependencies respectivement, au sein de votre package.json.

Compresser les réponses

Vous souhaitez normalement compresser les réponses venant du serveur. Si vous déployez déjà votre serveur derrière un proxy SSL ou un gestionnaire charge (load balancer), il est généralement plus efficace en termes de performances de gérer la compression à ce niveau-là, car Node.js ne peut utiliser qu’un seul thread.

Cependant, si vous compilez un serveur personnalisé et ne souhaitez pas y ajouter un middleware de compression, notez que nous vous recommanderions d’utiliser @polka/compression puisque SvelteKit streames ses réponses, et que le paquet compression, certes plus populaire, ne supporte pas le streaming, et pourrait donc provoquer des erreurs lorsqu’utilisé avec SvelteKit.

Variables d’environnement

En modes dev et preview, SvelteKit va lire les variables d’environnement dans votre fichier .env (ou .env.local ou .env.[mode], tel que déterminé par Vite.)

En production, les fichiers .env ne sont pas automatiquement chargés. Pour que ce soit le cas, installez dotenv dans votre projet...

npm install dotenv

... et invoquez le avant de lancer votre application compilée :

node -r dotenv/config build

Si vous utilisez Node.js v20.6+, vous pouvez utiliser l’option --env-file à la place :

node --env-file=.env build

PORT, HOST et SOCKET_PATH

Par défaut, le serveur va accepter des connections entrantes sur 0.0.0.0 en utilisant le port 3000. Ces valeurs peuvent être personnalisées avec les variables d’environnement PORT et HOST :

HOST=127.0.0.1 PORT=4000 node build

Comme alternative, le serveur peut être configuré pour accepter les connections entrantes sur un chemin de socket défini. Lorsque vous faites en utilisant la variable d’environnement SOCKET_PATH, les variables d’environnement HOST et PORT seront ignorées.

SOCKET_PATH=/tmp/socket node build

ORIGIN, PROTOCOL_HEADER, HOST_HEADER, and PORT_HEADER

HTTP ne fournit pas à SvelteKit une manière fiable de connaître l’URL qui est en train d’être requêtée. La manière la plus simple de dire à SvelteKit depuis où l’application est servie est de définir la variable d’environnement ORIGIN :

ORIGIN=https://my.site node build

# ou par ex. pour prévisualiser et tester
ORIGIN=http://localhost:3000 node build

Avec ceci, une requête pour le chemin /stuff sera correctement résolue en https://my.site/stuff. Alternativement, vous pouvez définir les en-têtes précisant à SvelteKit les protocole et hôte de requête, à partir desquels il va pouvoir construire l’URL d’origine :

PROTOCOL_HEADER=x-forwarded-proto HOST_HEADER=x-forwarded-host node build

x-forwarded-proto et x-forwarded-host sont des standards de facto qui relaient les protocole et hôte originaux si vous utilisez un reverse proxy (comme les load balancers et CDNs). Vous devriez uniquement définir ces variables si votre serveur est derrière un reverse proxy de confiance ; sinon, il peut être possible pour des clients de manipuler ces en–têtes (spoofing).

Si vous hébergez votre proxy sur un port non standard et que votre reverse proxy supporte l’en-tête x-forwarded-port, vous pouvez aussi définir PORT_HEADER=x-forwarded-port.

Si l’adaptateur adapter-node ne peut pas définir correctement l’URL de votre déploiement, il se peut que vous subissiez cette erreur lors de l’utilisation d’actions de formulaire :

Cross-site POST form submissions are forbidden (Les soumissions de formulaire cross-site POST sont interdites).

ADDRESS_HEADER et XFF_DEPTH

L’objet RequestEvent passé aux hooks et aux endpoints inclut une fonction event.getClientAddress() qui renvoie l’adresse IP du client. Par défaut il s’agit de l’adresse de connexion remoteAddress. Si votre serveur est derrière un ou plusieurs proxies (comme un load balancer), cette valeur contiendra l’adresse IP du proxy le plus profond et non celle du client, et il est donc nécessaire de spécifier ADDRESS_HEADER pour lire l’adresse :

ADDRESS_HEADER=True-Client-IP node build

Les en-têtes peuvent être facilement manipulées. Comme PROTOCOL_HEADER et HOST_HEADER, vous devriez savoir ce que vous faites avant de les définir.

Si la valeur de ADDRESS_HEADER est X-Forwarded-For, l’en-tête contiendra une liste d’adresses IP séparées par des virgules. La variable d’environnement X-Forwarded-For devrait spécifier combien de proxys de confiance se trouvent devant votre serveur. Par ex. s’il y a trois proxys de confiance, le proxy n°3 va relayer les adresses de la connection d’origine et des 2 premiers proxys :

<client address>, <proxy 1 address>, <proxy 2 address>

Certains guides vous recommanderont de lire l’adresse la plus à gauche, mais cela vous rend vulnérable à la manipulation d’en-têtes :

<spoofed address>, <client address>, <proxy 1 address>, <proxy 2 address>

Nous préférons lire les adresses depuis la droite, en prenant en compte le nombre de proxys. Dans ce cas, nous utiliserions XFF_DEPTH=3.

Si vous avez au contraire besoin de lire l’adresse la plus à gauche (et que vous ne vous souciez pas de la manipulation d’en-tête) — par exemple, pour offrir un service de géolocalisation, pour lequel il est plus important que l’adresse IP soit réelle que de confiance, vous pouvez faire cela en inspectant l’en-tête x-forwarded-for au sein de votre application.

BODY_SIZE_LIMIT

La taille maximale du body de la requête à accepter en bytes, en incluant ceux traités par streaming. La taille de body peut également être spécifiée avec un suffixe en kilobytes (K), mégabytes (M), ou gigabytes (G). Par exemple, 512K ou 1M. Cette valeur vaut par défaut 512kb. Vous pouvez désactiver cette option avec une valeur de Infinity (0 dans d’anciennes versions de l’adaptateur) et implémenter une vérification personnalisée dans la fonction handle si vous avez besoin de quelque chose de plus avancé.

SHUTDOWN_TIMEOUT

Le nombre de secondes à attendre avant de fermer les connexions restantes après avoir reçu un signal SIGTERM ou SIGINT. Vaut par défaut 30. En interne, l’adaptateur appelle closeAllConnections. Voir la section Arrêt propre pour plus de détails.

IDLE_TIMEOUT

Lors de l’utilisation de l’activation de socket via systemd, IDEL_TIMEOUT spécifie le nombre de secondes après lequel l’application est automatiquement mise en sommeil si elle ne reçoit plus de requêtes. Si non précisé, l’application n’est jamais mise en sommeil. Voir la section Activation de socket pour plus de détails.

Options

L’adaptateur peut être configuré avec différentes options :

svelte.config
import import adapteradapter from '@sveltejs/adapter-node';

export default {
	
kit: {
    adapter: any;
}
kit
: {
adapter: anyadapter: import adapteradapter({ // les options par défaut sont affichées out: stringout: 'build', precompress: booleanprecompress: true, envPrefix: stringenvPrefix: '' }) } };

out

Le dossier dans lequel compiler le serveur. Vaut par défaut build — c-à-d que la commande node build va pouvoir lancer le serveur localement une fois la compilation terminée.

precompress

Active la précompression en utilisant gzip et brotli pour les assets et les pages pré-rendues. Vaut par défaut true.

envPrefix

Si vous avez besoin de changer le nom des variables d’environnement utilisées pour configurer le déploiement (par exemple, pour éviter les conflits avec les variables d’environnement que vous ne contrôlez pas), vous pouvez préciser un préfixe :

envPrefix: 'MY_CUSTOM_';
MY_CUSTOM_HOST=127.0.0.1 \
MY_CUSTOM_PORT=4000 \
MY_CUSTOM_ORIGIN=https://my.site \
node build

Arrêt propre

Par défaut, l’adaptateur adapter-node éteint proprement le serveur HTTP lorsqu’un signal SIGTERM ou SIGINT est reçu. Il va faire les choses suivantes :

  1. rejeter les nouvelles requêtes (server.close)
  2. attendre que les requêtes déjà en cours mais n’ayant pas encore reçu de réponse puisse se finir et fermer les connections une fois qu’elles se mettent en attente (server.closeIdleConnections)
  3. et enfin, fermer toute connection restante qui serait toujours active après SHUTDOWN_TIMEOUT

Si vous souhaitez personnaliser ce comportement, vous pouvez utiliser un serveur personnalisé.

Vous pouvez écouter l’évènement sveltekit:shutdown qui est émis après que le serveur HTTP a fermé toutes les connexions. À la différence de l’évènement exit de Node, l’évènement sveltekit:shutdown supporte les opérations asynchrones et est toujours émis lorsque toutes les connections sont fermées même si le serveur a des opérations en cours comme des connexions ouvertes à des bases de données.

var process: NodeJS.Processprocess.NodeJS.Process.on(event: string | symbol, listener: (...args: any[]) => void): NodeJS.Process (+12 overloads)

Adds the listener function to the end of the listeners array for the event named eventName. No checks are made to see if the listener has already been added. Multiple calls passing the same combination of eventName and listener will result in the listener being added, and called, multiple times.

server.on('connection', (stream) => {
  console.log('someone connected!');
});

Returns a reference to the EventEmitter, so that calls can be chained.

By default, event listeners are invoked in the order they are added. The emitter.prependListener() method can be used as an alternative to add the event listener to the beginning of the listeners array.

import { EventEmitter } from 'node:events';
const myEE = new EventEmitter();
myEE.on('foo', () => console.log('a'));
myEE.prependListener('foo', () => console.log('b'));
myEE.emit('foo');
// Prints:
//   b
//   a
@sincev0.1.101
@parameventName The name of the event.
@paramlistener The callback function
on
('sveltekit:shutdown', async (reason: anyreason) => {
await jobs.stop(); await db.close(); });

Le paramètre reason a l’une des valeurs suivantes :

  • SIGINT - l’arrêt a été déclenché par un signal SIGINT
  • SIGTERM - l’arrêt a été déclenché par un signal SIGTERM
  • IDLE - l’arrêt a été déclenché par IDLE_TIMEOUT

Activation de socket

La plupart des systèmes d’exploitation Linux d’aujourd’hui utilisent un gestionnaire de processus moderne appelé systemd pour lancer un serveur et gérer les services. Vous pouvez configurer votre serveur pour allouer un socket, démarrer et dimensionner votre application à la demande. Ce processus est appelé activation de socket. Dans ce cas, l’OS va fournir deux variables d’environnement à votre application — LISTEN_PID et LISTEN_FDS. L’adaptateur va ensuite écouter le “file descriptor 3” qui fait référence à un socket systemd que vous devrez créer.

Vous pouvez toujours utiliser envPrefix avec l’activation de socket de systemd. LISTEN_PID et LISTEN_FDS sont toujours lus sans préfixe.

Pour tirer profit de l’activation de socket, veuillez suivre ces étapes.

  1. Lancer votre application en tant que service systemd. Elle peut soit être lancée directement sur le système hôte ou à l’intérieur d’un conteneur (avec Docker ou un service systemd portable par exemple). Si vous passez en plus une variable d’environnement IDLE_TIMEOUT à votre application, celle sera éteinte proprement lorsqu’elle ne recevra plus de requêtes pendant IDLE_TIMEOUT secondes. systemd va automatiquement démarrer de nouveau votre application lorsque de nouvelles requêtes arriveront.
/etc/systemd/system/myapp
[Service]
Environment=NODE_ENV=production IDLE_TIMEOUT=60
ExecStart=/usr/bin/node /usr/bin/myapp/build
  1. Créer une unité de socket d’accompagnement. L’adaptateur accepte uniquement un socket unique.
/etc/systemd/system/myapp
[Socket]
ListenStream=3000

[Install]
WantedBy=sockets.target
  1. Assurez-vous que systemd a reconnu les deux unités en lançant sudo systemctl daemon-reload. Puis activez le socket au démarrage et lancez-le immédiatement en utilisant sudo systemctl enable --now myapp.socket. L’application va alors automatiquement démarrer lors de la réception de la première requête sur localhost:3000.

Serveur personnalisé

L’adaptateur crée deux fichiers dans votre dossier de compilation — index.js et handler.js. Lancer index.js — c-à-d node build, si vous utilisez le dossier de compilation par défaut — va lancer un serveur sur le port configuré.

Autrement, vous pouvez importer le fichier handler.js, qui exporte un gestionnaire pouvant être utilisé avec Express, Connect ou Polka (ou même juste avec la méthode intégrée http.createServer), et lancer votre propre serveur :

my-server
import { import handlerhandler } from './build/handler.js';
import import expressexpress from 'express';

const const app: anyapp = import expressexpress();

// ajout d'une route qui vit séparément de l'application SvelteKit
const app: anyapp.get('/healthcheck', (req, res) => {

	res: anyres.end('ok');
});

// laiiser SvelteKit gérer tout le reste, incluant le fait de servir des pages pré-rendues et des
// assets statiques
const app: anyapp.use(import handlerhandler);

const app: anyapp.listen(3000, () => {
	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 calling require('console').

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
@seesource
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.

@sincev0.1.100
log
('écoute sur le port 3000');
});

Modifier cette page sur Github llms.txt