Skip to content

Safari fails to load islands: Unhandled Promise Rejection: ReferenceError: Cannot access uninitialized variable. #10055

@mb21

Description

@mb21

Astro Info

Astro                    v4.3.5
Node                     v18.17.1
System                   macOS (arm64)
Package Manager          npm
Output                   server
Adapter                  @astrojs/node
Integrations             @astrojs/solid-js

If this issue only occurs in one browser, which browser is a problem?

Safari (reproducable in Safari 17.3 on macOS and Safari on iOS 17.3)

Describe the Bug

I have two framework islands on my page (solid.js in this case, but I believe that's irrelevant). One of the islands sometimes fails to load completely. It's not always the same island that fails: sometimes both load, and sometimes one and sometimes the other (also sometimes it starts load, rendering something client-side, but then seems to fail later as the buttons are not working). Interestingly, the error logged to the safari console happens always in the DOM of the first island (even though that island then works perfectly fine, while the other one is broken):

In Safari dev tools it looks as follows (note which function call is underlined):
image

Here the relevant code as text:

                <script>
                (() => {
                    var e = async t => {
                        await (await t())()
                    };
                    (self.Astro || (self.Astro = {})).only = e;
                    window.dispatchEvent(new Event("astro:only"));
                })();

I've only managed to reproduce this in a production build, but even a production build running locally. All network requests completed with a 200.

Seems the code where the error occurs is just above this code. So probably it's an import that's generated by esbuild? That double await seems kinda funky anyway, or is that something you recognize?

I found this interesting comment on the svelte issue tracker:

We finally resolved this issue by removing the esnext build target in our vite config, which was there for a couple of top-level awaits. This bug in webkit is what ultimately made us try this update.

TL;DR:

[in Safari], the following code fails when importing the dependency more than once.

export let bar = 'foo'
await 0

I tried changing astro.config to:

export default defineConfig({
  vite: {
    build: {
      target: 'es2021',
    },
  ...

but when building then I get:

Top-level await is not available in the configured target environment ("es2021" + 2 overrides)

Somebody else has seen this error in their astro project and/or even managed to fix it?

What's the expected result?

All islands hydrate properly.

Link to Minimal Reproducible Example

So far I've not been able to reproduce this with a minimal example. Perhaps it requires a certain amount of code to trigger the race condition?

Participation

  • I am willing to submit a pull request for this issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    - P3: minor bugAn edge case that only affects very specific usage (priority)

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions