-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SvelteKit Process Hooks #693
Comments
What's wrong with the separate command? You can define "scripts": {
"build": "node scripts/prebuild.js && svelte-kit build"
} ...which would be a perfectly normal thing to do. |
@Rich-Harris another use case of these hooks could be to connect to a database when the server starts, to keep the connection alive. I was migrating a |
For I have a scenario where I need to connect to Kafka at application startup, so this'll be ideal for me :) |
You can create db connections etc in |
@cainux @shahidcodes I've been experimenting with this issue, specifically running initialization code. In a dev build, hooks.js seems to be dynamically imported when the first page is accessed. This may be due to the dynamic nature of dev environment (vite, HMR, etc.) In a prod build, hook.js is 'resolved' and available upon startup. I placed my initialization code outside of the exported functions (as a side-effect), and that code is being run upon startup. My hooks.js is at https://github.com/JBusillo/cuencador-kit/blob/master/src/hooks.js Feel free to peruse the project. I'm not sure if this behavior is intentional and will continue to work this way after SvelteKit goes beta or to production. But this approach may help you. |
If I can give my opinion, the documentation for the hooks module, https://kit.svelte.dev/docs#hooks, does not let it clear that it will keep a side-effect running in a node environment, like a database connection I think that's something that should be addressed, if that's the case |
Another observation: Any side effects of hooks.js are invoked during "build". This might prevent the build process from being truly "portable". By "portable", I mean being able to build a project on any machine without having to configure an application run environment (e.g., config files stored on the file system, database servers, etc.). I don't think that side effects in hooks.js need to be executed for the build process. My approach is to set an environment variable for the build script in package.json:
and conditionally execute side effects in hooks.js:
...and all of this depends on concerns expressed by @GCastilho and me -- being able to rely on side affect behavior and persistence within a node environment. [Note: There's also an environment variable: |
That's because of prerendering (SvelteKit can't know that you don't have any prerenderable pages without trying to prerender them). You can disable it in your config: module.exports = {
kit: {
prerender: {
enabled: false
}
}
}; It's possible that that should be the default. |
I was thinking that maybe it would be good to instead return one function from export async function setup() {
const db = await initMyDb();
return {
handle: (..) => ...
}
} |
I'm not sure I understand why we'd do that. Whenever I've written Express servers and the like, I've always just had a |
I understand what you're saying, Rich -- assuming that an Express server is handling the database calls. For small projects, it might be desirable/easier to use the server (Polka) in adapter-node to handle those calls -- i.e., only using the SvelteKit endpoints. Aside from the database use case, I have initialization code that pulls in json configuration files that contain app secrets, which creates a JS object that is used in my endpoints. This might not be the best approach -- I'm new to all of this. Personally, I'm satisfied with the 'workaround'. Maybe a more formal solution could be an enhancement in a future release. I know you're all busy getting the kinks out for SvelteKit 1.0 -- I appreciate your hard work and dedication. |
This is potentially a good use case for let secrets;
export async function getContext() {
return {
secrets: secrets || (secrets = await load_secrets_from_json())
};
} It might be more idiomatic to use environment variables though |
I generally dislike having code run as a side effect of importing a file. I personally like cainux's suggestion, of making a change to the node adapter, or creating a modified version, which calls a startup hook from server.js |
What about this? // src/hooks.js
import db from '$lib/db';
export async function handle(request, render) {
if (!db.ready) await db.init();
return render(request);
} |
That should work for me. I'll use the technique that you suggested. Thank you. |
So basically, the first time a page was rendered, the connection would be made. That works. I'm trying to think of situations where it doesn't, (ie: a microservice that responds to rest endpoints, or redis/kafka events, and has an html status page), but those are probably better suited to a different tool. |
Is there anything else we want to document here before closing this issue? |
The "How do I setup a database?" section under https://kit.svelte.dev/faq#integrations should be enough, we wouldn't want to write more stuff that is out of our scope |
I don't understand why people are suggesting to put it in the handle hook while others have concerns of it running multiple instances. When in this case, from some simple testing I just did, everything placed outside the hook functions runs once on server start up. |
Is your feature request related to a problem? Please describe.
As of right now, there's no real way to hook into the SvelteKit process to run code before build, dev, or start.
The SvelteKit
hooks.js
(not sure if this idea below works better for the formersetup.js
file), has hooks for when a route is called serverside. However, it'd be nice to have hooks that would essentially correspond withsvelte-kit build
,svelte-kit dev
, andsvelte-kit start
. Elder.js has "Build Hooks" that handle hooking into the build process. JungleJS also has ways of configuring async code in between build/start process steps.Describe the solution you'd like
My current idea is code like the following, probably in
hooks.js
.And then the
cli.js
file would be like it is now, but if one of these above (ofc optional) options is specified it runs it instead of the default code. For example, for the dev commandDescribe alternatives you've considered
My original idea were options for
preDev
,preBuild
, andpreStart
just in thesvelte.config.cjs
, for simplicity sake. This is of course kinda messy, and probably not the most dynamic way to do it. But also, these options for "process hooks" might not make sense in the currenthooks.js
file.How important is this feature to you?
In my efforts to recreate the ✨magic✨ of JungleJS within SvelteKit (take a look at progress here), I hit a road block where this is kinda critical. As of rn I have a literal
temp-cli.js
file that I'm using to pull in dataSources in a separate command. I could make a legit CLI for JungleJS, and will probably have to do so if this isn't pushed forward, but I feel this would be better as hooking into the whole SvelteKit process.Additional context
I decided to go ahead and make this an issue after seeing others ask for stuff that could be solved with this, one example here of where some sort of
preStart
hook would be useful.The text was updated successfully, but these errors were encountered: