Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No cloudflare object exposed to context in local environment #42

Closed
serban-mihai opened this issue Aug 22, 2024 · 6 comments
Closed

No cloudflare object exposed to context in local environment #42

serban-mihai opened this issue Aug 22, 2024 · 6 comments

Comments

@serban-mihai
Copy link

serban-mihai commented Aug 22, 2024

I'm trying to set up for local development a SolidStart App deployed to Cloudflare Pages that need to access some Bindings on SSR (server), KV, Durable Objects, and D1 in my case.
I followed a blog post that helped me get good binding types set up about this specific use case here: https://ryanjc.com/blog/solidstart-cloudflare-pages/

If deployed on Cloudflare Pages it works just fine and context gets the cloudflare.env that I'm collecting in a function to then use it in a "use server" function in a Solid component.

{
    "_nitro": {
        "routeRules": {}
      },
      "nitro": {
        "errors": []
      },
      "cf": {
        <ALL_CF_GEOLOCATION_AND_REQUEST_INFO>
        ...
      },
      "cloudflare": {
        "request": {},
        "env": {
          "ASSETS": {},
          <ALL_THE_BINDINGS_AND_VARIABLES_SET_IN_WRANGLER_TOML_ARE_HERE>
          ...
        },
        "context": {}
      }
    }

But in the local environment, no matter what I cannot get anything appearing in event.nativeEvent.context.

{ "_nitro": { "routeRules": {} } }

The local fallback of process.env mentioned in the article above has never been working for the same reason, so I turned out to this package. Still, it looks like nothing changed besides the run of wrangler at dev startup and the creation of /.wrangler/ folder where the local state is supposed to be kept during development.

Ideally, I would like to bind the Cloudflare Pages Functions (worker) to another Cloudflare Workers (worker) that I have locally run needed for the creation of Durable Objects since the Pages project cannot do it by itself. Still, there is no clear guideline to use without proxies, and the docs from all, Cloudflare, SolidStart, Nitro, and Discord discussions... are not of much help.

My use-case:

import { getRequestEvent } from "solid-js/web";
import { CfPagesEnv } from "~/global.d";

export const cloudflare = (): CfPagesEnv => {
  const event = getRequestEvent();
  return event?.nativeEvent.context.cloudflare?.env as CfPagesEnv
};
const getRooms = cache(async () => {
  "use server";
  const kv: KVNamespace = cloudflare().KV_NAMESPACE as KVNamespace;
  const rooms: RoomEntryType[] | null = await kv.get("rooms", "json");

  return rooms ?? [];
}, "lobby");

On deployed Cloudflare Pages Functions: All Good!
On local build command or dev command: Cannot read properties of undefined (reading 'KV_NAMESPACE')
I can't even build locally because of this.

My config:

import { defineConfig } from "@solidjs/start/config";
import nitroCloudflareBindings from "nitro-cloudflare-dev";

export default defineConfig({
server: {
    preset: "cloudflare_pages",
    rollupConfig: {
      external: ["__STATIC_CONTENT_MANIFEST", "node:async_hooks"],
    },
    modules: [nitroCloudflareBindings],
  },
})

All the bindings are correctly declared in wrangler.toml and referenced in globals.d.ts in the Pages project, autocomplete recognizes them.

Do you have any idea what I'm doing wrong?

@atinux
Copy link
Collaborator

atinux commented Oct 21, 2024

Would you mind sharing a small reproduction please?

@serban-mihai
Copy link
Author

Would you mind sharing a small reproduction please?

Since I wasn't able to find a solution, I abandoned the idea of using the nitro-cloudflare-dev entirely.
Instead, I've been able to make it work with a hack-ish strategy that is not somewhere near ideal nor feasible but it works for now using the getPlatformProxy from wrangler:

/global.d

/// <reference types="@solidjs/start/env" />
import type {
  Request as CfRequest,
  ExecutionContext,
  KVNamespace,
  DurableObjectNamespace,
} from "@cloudflare/workers-types";

export interface CfPagesEnv {
  ASSETS: { fetch: (request: CfRequest) => Promise<Response> };
  CF_PAGES: "1";
  CF_PAGES_BRANCH: string;
  CF_PAGES_COMMIT_SHA: string;
  CF_PAGES_URL: string;

  // Bindings
  LOBBY: KVNamespace;
  ROOM: DurableObjectNamespace;
  ...
}

declare module "vinxi/http" {
  interface H3EventContext {
    cf: CfRequest["cf"];
    cloudflare: {
      request: CfRequest;
      env: CfPagesEnv;
      context: ExecutionContext;
    };
  }
}

cloudflare.ts

import { getRequestEvent } from "solid-js/web";
import { CfPagesEnv } from "~/global.d";
import { getPlatformProxy } from "wrangler";

export const cloudflare = async (): Promise<CfPagesEnv> => {
  const event = getRequestEvent();
  const { env }: { env: CfPagesEnv } = await getPlatformProxy();  // comment before deploying on remote cloudflare pages

  if (!event?.nativeEvent.context.cloudflare) return env;   // comment before deploying on remote cloudflare pages
  return event?.nativeEvent.context.cloudflare?.env as CfPagesEnv;
};

Just use the (await cloudflare().<anything> as <anythin_type>) with <anything> being the binging anywhere you need to access some ENV variable or any other such as D1 or KV (it also works with Service Bindings). The major inconvenience is that you need to comment on the lines marked before deploying to remote or it will crash the build, and you also need to keep them uncommented during development to make the context available.

I'm sorry that I cannot provide you with an example of the library not working right now, but if you have other questions let me know.

@atinux
Copy link
Collaborator

atinux commented Oct 21, 2024

When I say reproduction, I mean a minimal Solid Start repository using this module with your server function not working locally (I don't have the time to create it myself sorry).

@serban-mihai
Copy link
Author

I'm sorry but I'm also running out of time.
Anyway, this module won't work in SolidStart until some changes are made as Ryan describes here

@atinux
Copy link
Collaborator

atinux commented Oct 21, 2024

Oh I see 😅

Well I don't know what to say, not sure to understand why SolidStart decided to not leverage Nitro server in development...
This creates a gap between dev & prod experience.

@pi0
Copy link
Member

pi0 commented Oct 22, 2024

This module is intended to work with an unmodified Nitro dev server and SolidStart (vinxi) does not leverage it. I hope at some point soon it will be solved let's track via solidjs/solid-start#1394

@pi0 pi0 closed this as not planned Won't fix, can't repro, duplicate, stale Oct 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants