OrJDev/create-jd-app

Can't import serverEnv from anything imported client-side (e.g. Co-located PRPC query + resolver)

ledburyb opened this issue · 2 comments

If you do this you will get the error "Invalid environment variables" as the client doesn't share the same environment.
I did find a few solutions to this, but they're not perfect and I'm not sure if I'm missing something obvious.

  1. Use isServer to conditionally populate the environment variables and then just lie to TypeScript at the type.
    e.g. export let serverEnv: ServerSchema = null as unknown as ServerSchema; if (isServer) { ... populate serverEnv }
    A big issue with this is that it still exposes your server environment keys in your client bundle (similar issue to t3-oss/t3-env#30)

  2. Do the same as for step 1, then also define your schema as a TypeScript type only and define it again as a Zod object inside an isServer guard. (This is what I'm currently using but it doesn't feel that clean)

  3. Use Vite / TypeScript imports to change the import for the client bundle (As described in vitejs/vite#4172 (comment))

OrJDev commented

Yes that is a known bug in dev mode as vite doesn't tree shake in dev, for instance if you use NextJS with prpc this issue will not occur because NextJS does treeshake, there is an opened issue for this in solid start, if you want to try, build the project then start it instead of using dev

solidjs/solid-start#850

OK, the best workaround I can come up with for now that lets it run in dev and doesn't seem to put any of the env keys in the bundle is:

  1. Change schema.ts to export a function that returns the schema instead of the schema itself
  2. Change server.ts to conditionally use that function and otherwise fudge the return type:
function getServerEnv() {
  const env = getServerSchema().safeParse(process.env);
  if (env.success === false) {
    console.error(
      "❌ Invalid environment variables:\n",
      ...formatErrors(env.error.format())
    );
    throw new Error("Invalid environment variables");
  }
  return env.data;
}

export const serverEnv = isServer
  ? getServerEnv()
  : (null as unknown as z.infer<ReturnType<typeof getServerSchema>>);