kit: SvelteKit 2: Importing `$env/dynamic/public` in safari causes a `Cannot access uninitialized variable` on hydration
Describe the bug
My company tried upgrading our app to SvelteKit 2, except that using it on Safari would always cause a panic both in dev mode and a production build. SvelteKit 1 still works fine.
I was trying to investigate the bug, and was able to reproduce it in dev mode by just importing $env/dynamic/public
from a layout file more than once. I assume that a production build does some tree shaking or something that prevents it from being reproduced in such a contrived way.
Reproduction
This link should fail on dev mode in Safari with Cannot access uninitialized variable
. All of my coworkers who tried it in Safari also experienced the same behavior.
https://stackblitz.com/edit/sveltejs-kit-template-default-ankg48?file=src%2Froutes%2F%2Bpage.svelte
Logs
[Error] ReferenceError: Cannot access uninitialized variable.
validate — exports.js:12
(anonymous function) — client.js:519
handleError (app.js:16)
handle_error (client.js:1485)
(anonymous function) (client.js:2088)
System Info
Safari 16.5, Ventura 13.4
Severity
blocking an upgrade
Additional Information
I recognize this bug is similar to https://github.com/sveltejs/kit/issues/2889 but we’ve been able to reproduce it consistently, and changing any build parameters doesnt fix it.
Any help in solving this would be appreciated, as we really want to use Shallow Routing!
About this issue
- Original URL
- State: closed
- Created 6 months ago
- Reactions: 17
- Comments: 23 (7 by maintainers)
Commits related to this issue
- fix: dynamic env import Ref: https://github.com/sveltejs/kit/issues/11364 — committed to eXodes/releve by eXodes 6 months ago
- feat: mobile pwa improvement (#69) * feat: vite pwa manifest * feat: pwa images * fix: app metadata * fix: mobile nav slider * chore: prettier format * fix: vite pwa type * fix: vit... — committed to eXodes/releve by eXodes 6 months ago
- Merge branch 'main' into gh-11364 — committed to sveltejs/kit by Rich-Harris 6 months ago
We are using both $env/dynamic/public and $env/dynamic/private. Please see the minimal reproduction above, as it can be reproduced in its simplest form by indirectly including the
$env/dynamic/public
module more than once.Regardless of the possibility of working around the issue, it seems like there may be a bug in how the generated javascript in the minimal case above is being output with regard to Safari
Regardless of static or dynamic, it still shouldn’t be causing a hard crash in only one browser by just importing it. In our production app, we need some server side secrets, so putting everything in static isn’t feasible.
fixed in 2.3.2
Safari has a bug in its global await implementation, as #7805 points out, the following code fails when importing the dependency more than once.
This is why importing “$env/dynamic/public” is causing issues in SvelteKit v2 in Safari
Any update on this issue?
I can confirm that it is not just Safari for Mac that experiences this. It breaks iOS devices as well.
In 94391905f7deb33f830f3fb76df4289833ccf3bd the
exports/vite/index.js
the line:was changed into:
this is causing the
ReferenceError: Cannot access uninitialized variable.
in Safari/WebkitWe have the same error (Unhandled Promise Rejection: ReferenceError: Cannot access uninitialized variable.) on upgrading from SK1 to SK2.
It is occurring in our npmjs library app where we are having the problem (and is propagating to our production apps). That library app does NOT use ANY env variables. So, I wonder if that is a red herring.
Some routes work fine, but others experience this problem EVERY time when first navigating to them, but navigating somewhere else, and then back shows the page correctly.
We have been trying to track down what offending code in our app is doing this, but still haven’t been able to figure it out.
Note: I’ve copied the offending code below. The error occurs on the line with the ‘constructors’ prop. I’m guessing the issue might have something to do with the forced @ts-ignore on the line above:
props: { // @ts-ignore Somehow it’s getting SvelteComponent and SvelteComponentDev mixed up constructors: compact(branch).map((branch_node) => branch_node.node.component), page }