opral / inlang-paraglide-js

Tree-shakable i18n library build on the inlang ecosystem.
https://inlang.com/m/gerre34r/library-inlang-paraglideJs
52 stars 1 forks source link

sveltekit cloudflare adapter can't work with paraglide #163

Closed nosovk closed 4 months ago

nosovk commented 5 months ago

There is an "node:async_hooks" used inside sveltekit adapter. https://github.com/opral/monorepo/blob/606c8d8f18302a35a7356206a9b1c480e9c8191b/inlang/source-code/paraglide/paraglide-sveltekit/src/runtime/hooks/handle.server.ts#L10

but unfortunately it's not supported in cloudflare pages environment.

nosovk commented 5 months ago

"@inlang/paraglide-sveltekit": "^0.6.23" works, rolled back to it

nosovk commented 5 months ago

https://nodejs.org/api/async_hooks.html actually it's recommended not to use it all

LorisSigrist commented 5 months ago

The AsyncLocalStorage API should be available in Cloudflare Workers & Pages.
https://developers.cloudflare.com/workers/runtime-apis/nodejs/asynclocalstorage/

You do need to set compatibility_flags = [ "nodejs_compat" ] in wrangler.toml.

Does the issue go away if you add that?

it's recommended not to use it all

Yes, AsyncLocalStorage is an experimental API, but it is already widely used in production & isn't going anywhere. NextJS uses it extensively in the App router.

Edit: compatibility_flags = [ "nodejs_als" ] is a more light-weight alternative to compatibility_flags = [ "nodejs_compat" ]

nosovk commented 5 months ago

nodejs_compat is not recommended, it affects performance of cloudflare workers, if possible it's better not to activate it. Actually enabling it is a blocker to upgrade to current paraglide version.

LorisSigrist commented 5 months ago

I might be able to replace AsyncLocalStorage with unctx and their build-time vite-plugin.

I'll try that & get back to you

samuelstroschein commented 4 months ago

More users are running into this problem. See discord https://discord.com/channels/897438559458430986/1083724234142011392/1256638811769667695

EDIT: Better workaround than settings nodejs_compat:

CleanShot 2024-06-29 at 12 02 06@2x

LorisSigrist commented 4 months ago

I tried substituting AsyncLocalStorage with unctx, but it unfortunately does not work reliably.

Given that the nodejs_als flag is available on Cloudflare and it has a much smaller performance penalty than the full-blown nodejs_compat we are not going to remove AsyncLocalStorage. We instead recommend just using the nodejs_als flag.

We will add documentation telling people about the usage of AsyncLocalStorage & how to deploy it on CloudFlare.

We are of course open to alternative solutions if you have ideas

Why we use AsyncLocalStorage When server-rendering multiple requests may be processed concurrently. We want to avoid the language of one request overriding the language of another. The only way of doing this reliably is with AsyncLocalStorage (or by manually passing the language everywhere). Frameworks like NextJS and SolidStart make heavy use of AsyncLocalStorage for the same reason.

nosovk commented 4 months ago

Solid does not requre that flag according to documentation https://developers.cloudflare.com/pages/framework-guides/deploy-a-solid-site/

In edge adapters there is no parallel execution of multiple requests in one env, that's why there is no benefit from from AsyncLocalStorage in CloudFlare Pages adapter, Vercel adapter etc.

It' could be helpful if you use node adapted, but actually I never saw it working like that in production (due of performance issues, which are solved by edge funktions architecture).

I hope that in future releases there will be an option to opt out of that.

LorisSigrist commented 4 months ago

You're right. On serverless providers there is no need to protect against requests interfering.

How about this, we'll keep AsyncLocalStorage on by default, as it's the safe base-case, and add an option on i18n.handle() to disable it if you know what you are doing

nosovk commented 4 months ago

https://github.com/opral/monorepo/blob/main/.changeset/fast-stingrays-leave.md

misaelvillaverde commented 4 months ago

I have the same issue with astro + cloudflares, neither using nodejs_compat nor nodejs_als works for me though. I will just try to rollback.

[plugin vite:resolve] Cannot bundle Node.js built-in "node:async_hooks" imported from "node_modules/@inlang/paraglide-astro/dist/middleware.js"
nosovk commented 3 months ago

@misaelvillaverde we just pinned old version, but it seems that there is a option (but not documented) to disable that experimental things now.