libauth
libauth copied to clipboard
Issue on Safari : Promise Rejection: ReferenceError: Cannot access uninitialized variable.
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
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.
Hi @bitjson , thank you for the feedback. Yes I think you might be right. Please excuse the noise :)
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" ?
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.
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
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.
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.
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).
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)