-
-
Notifications
You must be signed in to change notification settings - Fork 2k
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
Route-level deployment config #8383
Comments
This sounds like a good solution, including for the case I raised in #8310. Re: api route inheritance, I think having a default config in the adapter that can be overridden in a particular route/tree makes sense, since global config will be the majority use-case. I agree having api routes inherit this config from routes but not others would lead to confusion. In the case I outlined you can then just leave the default and opt-in to the edge in the root layout, which api routes won’t inherit. Feels right to my brain. I definitely think merging config objects in overrides makes a lot more sense, especially since there’s no way to access the parent object to merge stuff yourself, otherwise you’ll have a lot of duplication to keep track of. And finally the only reason I kind of like the alternative of keeping everything in adapter config is an irrational one — adapters don’t really feel like part of Sveltekit ‘core’, but something you can swap and change at any time for different environments, so it feels cleaner to have their config seperate rather than littered in your app code. Again though in practice this has no real practical downside, just the vibe of the thing |
Coming from #8458. I really like the Maybe outside the scope of this issue, but we may need a way to properly handle |
Describe the problem
We've talked about this obliquely in #7716 and #7845 and elsewhere, but haven't really fleshed it out.
#8310 articulates the idea well: it's often the case that some parts of your app are suitable for edge runtimes, while others require Node modules; some things make sense to deploy to the edge, other things belong physically close to your database. At present, deployment configuration is per-app — if you're using
adapter-vercel
(for example) you can use edge functions or lambdas, but you can't use both in one app.Describe the proposed solution
In #7716 I proposed this:
Here,
config
is whatever shape makes sense for the adapter you're using. After the app is built, SvelteKit would read the config from each entry point (by actually importing the module, not by static analysis which would prevent the use of things like environment variables or re-exports from$lib/config
or whatever) and associate it with the route. This config would then be accessible to the adapter, which would use it to configure the deployment. (Note that reading the config happens in a separate process, which means it must be serializable using devalue or whatever.)Layout config
As with other page options,
export const config
from a+layout.js
or+layout.server.js
would apply to all child pages unless it was overridden.Overriding could take one of two forms — merging or replacing. In other words this...
...could result in this for the
/whatever
route (where 'runtime' is undefined and therefore whatever the default value is)......or this:
I suspect merging would be more helpful in practice.
One thing to note is that in the
export const prerender
case, API routes do not inherit from layouts. For consistency, we'd probably want to do the same forexport const config
. In the case described in #8310, where everything in/api
needs a Node runtime, this might be unhelpful. Possible solutions:export const config
altogether (see 'Alternatives considered')Types
We could add a new
App.RouteConfig
interface. This could be declared inside the adapter's types, and would be automatically picked up.In the glorious future where we somehow type exports automatically (either microsoft/TypeScript#38511 or a TypeScript plugin, even this would be unnecessary for type-safe configuration.
Dev
One important consideration is how this interacts with #3535. The tl;dr is that we'd like to actively prevent you from using Node APIs/modules like
Buffer
ornode:fs
in a route that will be deployed to the edge; conversely it would be cool if you could use platform-specific stuff that wouldn't normally be available in Node in applicable functions.Simply running the dev server inside a simulation of the production runtime (well, not simply — that would probably be quite hard) doesn't solve the problem, because it's quite possible to use
node:fs
in a prerendered page in an otherwise edge-deployed app.Two basic approaches spring to mind: SvelteKit itself is somehow aware of the different environments, and
config.runtime
is a common property with a restricted set of values, or each adapter needs to somehow augment the dev server environment with additional APIs and modules and provide a hook for detecting the use of forbidden APIs and modules. I suspect the adapter approach is preferable (it allows adapter config such asedge: true
to be taken into account, and is probably more future-proof), and it gives us a bit more flexibility in designing this feature since we don't need to solve both things at once, but it would be good to have some idea of what the implementation would look like so that we don't accidentally paint ourselves into a corner.Conventions
While the shape of
App.RouteConfig
would be adapter-specific, it's likely that certain conventions would emerge. For example the Vercel and Netlify adapters could both useruntime
to configure edge vs lambda, and possiblygroup
to configure splitting behaviour if someone wanted manual control. I'm not sure if Netlify allows you to configure multiple regions per deployment, but if so both could also use aregion
property.Other adapters would doubtless have overlapping uses. While the shape of the config wouldn't be enforced anywhere, it would be nice if adapters organically adopted the same conventions.
Alternatives considered
The alternative to route config is to do everything inside the adapter, perhaps by having a function that took a route ID and returned the relevant config.
In general I like this less than the declarative approach, but it might be nicer in certain circumstances, like switching behaviour based on whether a route is a page or an API route as in the example above.
Importance
would make my life easier
Additional Information
No response
The text was updated successfully, but these errors were encountered: