#Deployments to Cloudflare Workers

1 messages · Page 1 of 1 (latest)

charred meadow
#

Is there a particular reason why Start don't support the cloudflare_module preset even though Nitro supports it?

I assumed since Start is built on Nitro that it would support any presets that Nitro does out of the box.

#

Or is it a Vinxi issue? The error/warning seems to be from Vinxi. The app seems to build okay and I can run it locally using wrangler, so not sure how it will work when deployed.

last bison
#

it might magically disappear once we are off vinxi

charred meadow
#

Any ~ETA when v1 will be out without Vinxi? I'm busy looking at an alternative to Next.js and currently between TanStack Start and React Router v7 - leaning towards Start since it feels like it took the best parts of Next.js and RR, but also aware of the pre-v1 release. Cloudflare Workers support is important to me.

last bison
#

version without vinxi will hopefully take no more than a few weeks

fossil blaze
#

I'm running cloudflare worker module in prod. Have run into some limitations. But overall works.
app.config.js

export default defineConfig({
  server: {
    preset: "cloudflare-module",
    unenv: cloudflare,
  },
  vite: {
    build: {
      rollupOptions: {
        external: ["node:async_hooks"],
      }
    }
  }
  ...
}

To get cloudflare env in dev and prod I have helper function

import { getEvent } from "vinxi/http";
import { Env } from "worker-configuration";

type CfEnv = {
  env: Env;
  waitUntil: (promise: Promise<unknown>) => void;
};

const getDevProxy = async () => {
  const cf = await import("wrangler");
  return await cf.getPlatformProxy<Env>({ persist: true });
};

let ___devProxy: ReturnType<typeof getDevProxy> | undefined = undefined;

export const getCloudflareContext = async (): Promise<CfEnv> => {
  const event = getEvent();
  if (import.meta.env.DEV) {
    // Attach the cloudflare context
    if (!___devProxy) {
      ___devProxy = getDevProxy();
    }
    const proxy = await ___devProxy;
    return {
      env: proxy.env,
      waitUntil: (promise: Promise<unknown>) => proxy.ctx.waitUntil(promise),
    };
  } else {
    return {
      // @ts-expect-error fighting with getting the types injected
      // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
      env: event.context.cloudflare.env as Env,
      waitUntil: (promise: Promise<unknown>) => {
        // @ts-expect-error fighting with getting the types injected
        // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
        event.context.cloudflare.context.waitUntil(promise);
      },
    };
  }
};

The only problem I'm really running is that for some reason I cannot use that in server function in loader functions. Especially beforeLoad, for some reason in that context the getEvent evnet doesn't have the cloudflare there 😱 but when server function is called from client side it works

#

But as I'm running with Clerk auth that doens't really matter, as Clerk doesn't have true SSR, so the app is more or less just SPA with server functions. And most of my backend logic is deployed as trpc server else where as I have multiple different consumers.

And migrated away from RRv7. The migration from Remix was not fun. And started running into all kind of annoying issues here and there. And this comes from almost 3 years of happy remix use

last bison
#

as soon as we have something testable without vinxi I will let you know so you can test with cloudflare

keen mist
mystic spindle
keen mist
# mystic spindle Can you share a repo of this?

I not sure is this help, but i get the code running by doing this:

// Example: Work

// cloudflare.ts
import { getEvent, H3EventContext } from '@tanstack/react-start/server'

export const getCloudflareCtx = async (): Promise<H3EventContext['cloudflare']> => {
  if (import.meta.env.DEV) {
    const wrangler = await import('wrangler')
    const proxy = await wrangler.getPlatformProxy<Env>()
    return proxy
  }

  const event = getEvent()
  return event.context.cloudflare
}

// index.tsx
const test = createServerFn({ method: 'GET' })
  .handler(async () => {
    const ctx = await getCloudflareCtx()

    console.log(ctx.env.MODE)

    return ctx.env.MODE
  })

export const Route = createFileRoute('/')({
  component: RouteComponent,
  beforeLoad: async ({ context }) => {
    context.queryClient.fetchQuery({
      queryKey: ['test'],
      queryFn: test,
    })
  },
})
// Example: Not working

// index.tsx
export const Route = createFileRoute('/')({
  component: RouteComponent,
  beforeLoad: async ({ context }) => {
    test() // direct call the server function, the getCloudflareCtx will return you undefined in the test server function. 
  },
})

I don't know why it's work, but this is the solution i got. Sorry for that i can't make this as a repo.

fossil blaze