-
Notifications
You must be signed in to change notification settings - Fork 511
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
feat: support dynamic app config and runtime config #1154
Conversation
Codecov Report
@@ Coverage Diff @@
## main #1154 +/- ##
==========================================
+ Coverage 76.96% 77.03% +0.06%
==========================================
Files 67 67
Lines 6613 6613
Branches 719 726 +7
==========================================
+ Hits 5090 5094 +4
+ Misses 1522 1517 -5
- Partials 1 2 +1 see 3 files with indirect coverage changes Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. |
However this PR is fully backward/compatible with Nuxt, would be happy to hear feedbacks from @unjs/nuxt team members if there are real concerns about this direction and waiting for a while before moving this forward to edge. |
β Live Preview ready!
|
Any feedback regarding this @danielroe ? |
I'm planning to have a look today. |
I really like this approach conceptually and think it makes sense π Nice work. |
Update: More thinking mutable config with ambient context, can be an unsafe change especially if go unnoticed by developers. For now, ambient context composables, remain frozen (but cloned). This means that for now, This is not final. In next steps, i plan to work on (mentioned above) proxy package that can enable us internally tracking and mutating a frozen public interface. This way we can avoid both clone costs and also internally apply envs even for ambient frozen public config. |
π Linked issue
β Type of change
π Description
The initial implementation of both runtime-config and app-config are using a deep frozen version of the build-time config so that it is safe to be shared across requests. However, both app-config and runtime-config are by design dynamic configuration sources.
Dynamic Runtime config
When using
useRuntimeConfig()
in an ambient context, it uses a shared, cloned, andmutablefrozen object.When using the new
useRuntimeConfig(event)
, cloned object will be cached in the request event. Whenever we call the composable, the latest environment variables will be applied. This supports dynamic env updates as well as Cloudflare module/pages environment compatibility (unjs/unenv#95)Dynamic App Config
When using
useAppConfig()
in an ambient context, it returns a shared, cloned, andmutablefrozen version of the app config. This is mainly for backward compatibility and is not shared with non-ambient versions.When using
useAppConfig(event)
, it returns a cloned and mutable version of the app config suitable to be dynamically extended per request without leaking context across requests.Side note: Nuxt can integrate with the new mutable
useAppConfig
API of nitro by exposing it from the renderer to the rest of the app) and augmenting with next-specific app-config that might be tree-shaken from the nitro side. This way app config can be universally extended. SinceuseAppConfig
from nuxt is already a context-aware composable it access to the event.Other notes
Thinking today about dynamic config sources, we should have avoided the ambient context usage for such composables. This PR adds a new feature as an enhancement with fully backward compatibility and without breaking changes but i am thinking to slowly starting deprecating ambient usage and replacing it with a better and clear way for exposing that kind of build-time static configurations. Starting by updating docs and maybe a warning once there was the better alternative in place and widely adopted by Nitro and Nuxt.
This implementation is using klona which according to their benchmarks at least is one of the fastest possible solutions. structured clone as alternative, is not possible within workers. A defu based clone (unjs/defu#90) could be used. But i am also thinking to implement change sets as a smart Proxy with lazy cloning per request. If we have it, it can be also useful for smart app-config hydration from server to client and only including changes.
π Checklist