libauth icon indicating copy to clipboard operation
libauth copied to clipboard

Issue on Safari : Promise Rejection: ReferenceError: Cannot access uninitialized variable.

Open cge-taal opened this issue 1 year ago • 8 comments
trafficstars

Hi,

Thank you for the nice library. Sadly, it seems there is an issue on Safari.

Please refer to

  • https://github.com/sveltejs/kit/issues/12406
  • https://github.com/cge-taal/sveltekit-safari-ssr-example

The example repository above is to illustrate the problem via a small reproducible example. However, in a rather big code base, libauth is the only dependency which is having issues in Safari, failing with Promise Rejection: ReferenceError: Cannot access uninitialized variable..

Therefore I imagine it has to do with how libauth is packaged, and not something intrinsic to vite / sveltekit.

Would appreciate it if you could take a look.

Thanks

cge-taal avatar Jun 28 '24 10:06 cge-taal

Is this a bug (or rather, a missing feature) in Svelte? https://github.com/sveltejs/svelte/issues/5501

Libauth uses top-level await to simplify instantiation/management of the WASM crypto implementations.

bitjson avatar Jun 29 '24 18:06 bitjson

Hi @bitjson , thank you for the feedback. Yes I think you might be right. Please excuse the noise :)

cge-taal avatar Jul 01 '24 07:07 cge-taal

Hi @bitjson, according to this comment ( https://github.com/sveltejs/kit/issues/12406#issuecomment-2211159175 ) "Libraries and even SvelteKit need to be refactored to avoid the use of top-level awaits in the browser."

What is your take on that please? Is it feasible to load WASM routines in your library without the use of "top-level awaits in the browser" ?

cge-taal avatar Jul 06 '24 20:07 cge-taal

I realize I'm a bit late to this party, but was experimenting with Svelte(Kit) recently.

I was only able to get this working through a bit of trial+error (aided by scattered Google searches). In case it helps anyone in future:

For vite.config.js, I did:

import { sveltekit } from '@sveltejs/kit/vite';
import { defineConfig } from 'vite';
import { nodePolyfills } from 'vite-plugin-node-polyfills';

export default defineConfig({
	plugins: [sveltekit(), nodePolyfills({
	  // This was for the electrum-cash library... unrelated, but copying here in case pertinent as example to others.
	  include: ['event', 'net', 'tls'],
	})],
	build: {
	  target: "es2022"
	},
	esbuild: {
	  target: "es2022"
	},
	// NOTE: This was important! Top-level await would not work without this!
	optimizeDeps:{
	  esbuildOptions: {
		target: "es2022",
	  }
	}
});

... and in svelte.config.js I did:

const config = {
        // ...
	viteFinal: async (config) => {
		if(!config.build) {
			config.build = {};
		}
		config.build.target = ['esnext'];
		return config;
	}
        // ...
}

I think I recall reading that svelte.config.js will overwrite some of the build configurations used in vite.config.js (because it uses some custom build setup and depending upon Vite's config would break this). Hence why we need to muck about with the viteFinal object there.

jimtendo avatar Sep 01 '24 02:09 jimtendo

Hi @jimtendo , what a nice surprise to see movement on this. I did not get round to trying more things yet, so I'm excited to see if your solution works for me too. Will report back in the next days. Thanks for sharing

cge-taal avatar Sep 01 '24 20:09 cge-taal

I could not help myself and had to try quickly. Are you sure your changes allow it to work in Safari? Please see the screenshot attached for the error in Safari. safari-issue

My config was already working to allow libauth to be used in SvelteKit. This ticket is really only to report issues with Safari. As someone in the SvelteKit community suggested, given there is a bug regarding top-level async await support in the Safari web browser, the only real solution would be to refactor libraries, in this case libauth, to not use top-level async await, unfortunately.

cge-taal avatar Sep 01 '24 21:09 cge-taal

I'm very sorry, I'd actually completely missed that your issue was Safari!

I did not test that - but suspect I would've bumped into the same issue you have.

Not sure if it's of help to you (I kind of doubt it would work), but there is a Top-Level-Await polyfill I've used on Quasar projects successfully to support old versions of KDE's Falkon browser: https://www.npmjs.com/package/vite-plugin-top-level-await

No idea if that would work on your case as it seems that Safari does support Top-Level-Await already (so polyfill probably wouldn't apply itself).

jimtendo avatar Sep 02 '24 05:09 jimtendo

Hi @jimtendo , not worries at all - thanks for trying to help.

If you are curious, I don't need a viteFinal section in my svelte.config.js, and my vite.config.ts has

import { sveltekit } from '@sveltejs/kit/vite'
import { defineConfig, type UserConfigExport } from 'vitest/config'
import browserslistToEsbuild from 'browserslist-to-esbuild'

export default defineConfig({
  ...,
  target: browserslistToEsbuild(),
  plugins: [sveltekit()],
  optimizeDeps: {
    esbuildOptions: {
      target: 'esnext',
    },
  },
  build: {
    target: 'esnext',
    commonjsOptions: {
      include: [ ..., /node_modules/ ],
    },
  },
} as UserConfigExport)

cge-taal avatar Sep 02 '24 07:09 cge-taal