Lazy values
Sometimes you can only get a value after the module where it should be serialized to is created. When using the AIK Plugin, for example, you can only define an inline module during the astro:config:setup
hook, but you might want to serialize a value from other hooks.
For such use cases, you can use the lazyValue
utility to create a placeholder value that you can set later:
Under the hood
Internally this utility will park the module inspection and serialization in Node’s event loop such that it can be resumed once, and only once, the value of the lazy value is set. This allows for as much of the inspection/serialization work to be done preemptively, and not wait for the value to be set.
During the module resolution, anything awaiting on the load
event of the virtual module will also be parked until the value is set.
Requirements
When using lazyValue
you must guarantee some invariants about the code using it. Failing to do so will cause serious problems in your project, ranging from deadlocks to unsafe code execution on your server.
Set value on all possible code paths
There must not be any possible code path where a lazy value is not set.
Example
If the API call to the remote config fails or if the response is not valid JSON, the value will not be set.
Do this instead:
Set value before bundling completes
The value must be set before Vite’s bundling is expected to complete (and here we say expected because if you don’t set the value, Vite will never complete the bundling).
Example
In the following code, pagesData
is set on an Astro hook that runs before Vite’s bundling, allowing the pages data to be serialized.
On the other hand, pagesDataLate
is being set on an Astro hook that runs after Vite’s bundling, this is not allowed. Using the pagesDataLate
value will lead to problems.
No self dependency
The value must not depend on it’s own serialization, neither directly on it’s value, or indirectly due to control flow.
Example 1: Value is set to it’s own serialization
Example 2: Value is not set unless serialized
In this case the value doesn’t seem to depend on itself, but it does. It is only set after it is serialized, but it can’t be serialized until it’s set, so even though the value being set is independent of the serialization the action of setting the value is not.