skip to Main Content

The env:

  • sveltekit 1.20.4
  • svelte 4.0.5
  • vite
  • adapter-node

How do I run startup code, before the server starts handling requests?
I need to start multiple services before a single request is handled, and for it to happen when I start the server, not when the first hook runs in hooks.server.js.
I tried putting some init functions outside the handle hook but then they run during build because of ESmodules/tree shaking.

Edit: Elaborating a bit, since it isn’t very obvious what the implications are. Assuming the goal is to have a DB class you can import and use anywhere in the project, so within a +server.js file for example, you’d import the class and init() it somewhere. If the startup script is meant to init(), then it can’t be part of the build process, because the build will run the top level code and try to establish connections. It not being part of the build process means I can’t just `import db from ‘db’; because the output of the build generates dozens of chunk files which won’t be in the correct locations, or have the same name as before.

hooks.server.js

import db from 'db';
import redis from 'redis';
import wss from 'websocket';

const runAllTheInitFunctions = async () => {
    await db.init();
    ...
}

await runAllTheInitFunctions(); // Can't go here, so... where?

/** @type {import('@sveltejs/kit').Handle} */
export const handle = async ({ event, resolve }) => {
    ...
}

I must be missing something obvious, so hopefully someone has found an elegant solution aside from checking init on every handle().
Thank you in advance.

2

Answers


  1. Chosen as BEST ANSWER

    Somehow missed this in the docs after reading them over multiple times. Found a reference to it in a git issue.

    https://kit.svelte.dev/docs/building-your-app#during-the-build

    The answer is I run the code exactly like before, at the top of my hooks.server.js file, but adding a check to see if it's running within a build:

    import db from 'db';
    import redis from 'redis';
    import wss from 'websocket';
    import { building } from '$app/environment'; // <---- here
    
    const runAllTheInitFunctions = async () => {
        await db.init();
        ...
    }
    
    if (!building) {                             // <---- here
        await runAllTheInitFunctions();
    }
    
    /** @type {import('@sveltejs/kit').Handle} */
    export const handle = async ({ event, resolve }) => {
        ...
    }
    

  2. The Node adapter generates a middleware handler, so you could just set up a server script that contains your startup logic and uses the handler.

    Abridged example from docs:

    import { handler } from './build/handler.js';
    import express from 'express';
     
    const app = express();
    app.use(handler); 
    app.listen(3000, () => {
      console.log('listening on port 3000');
    });
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search