getBindingsProxy Mess - leads to build errors

Love the idea of that method - makes my code really nicer. Now - to use it i need to: import { getBindingsProxy } from "wrangler"; this for sure results in an "cannot find package wrangler" so i move wrangler from dev dependencies to dependencies. after restart, it than complains that it wants to load the full wrangler inside of wranger - resulting in nodejs errors like: X [ERROR] Could not resolve "fs/promises"

../../node_modules/.pnpm/miniflare@3.20240129.0/node_modules/miniflare/dist/src/index.js:2506:30:
2506 │ var import_promises = require("fs/promises"); ╵ ~~~ The package "fs/promises" wasn't found on the file system but is built into node. Are you trying to bundle for node? You can use "platform: 'node'" to do that, which will remove this error. X [ERROR] Could not resolve "worker_threads"

../../node_modules/.pnpm/miniflare@3.20240129.0/node_modules/miniflare/dist/src/index.js:5159:36:
5159 │ var import_worker_threads = require("worker_threads"); ╵
~~~~~~ The package "worker_threads" wasn't found on the file system but is built into node. Are you trying to bundle for node? You can use "platform: 'node'" to do that, which will remove this error. as for sure, these APIs are not available when loaded inside of wrangler. So, how to solve this?
11 Replies
Dario
Dario4mo ago
Hi @piffie thanks for the interest in the method 😃 I haven't seen this issue but I've used the utility in different Node.js apps (like for example this simple one: https://github.com/dario-piotrowicz/getBindingsProxy-poc-demo) So I'm surprised that it's breaking for you 😕 Would it be possible for you to share your setup/code?
piffie
piffie4mo ago
as soon as i add wrangler to the dependencies and run pnpm i, and then pnpm dev, the compiler writes me these errors. when i remove it again from the dependencies, its fine (but cannot find wrangler for the import)
Dario
Dario4mo ago
Hey @piffie did you edit your question above? because you either did or I misunderstood things last time I read it 😅 where are you trying to run the utility from? not inside a worker right?
piffie
piffie4mo ago
@Dario I was trying to run it inside a worker, yes. How else should it be used? would be a really neat feature to access the bindings without needing to pass it down all the time.
Dario
Dario4mo ago
I see, sorry for the misunderstanding
How else should it be used?
The utility is to be used in node.js apps to simulate the Cloudflare "platform", this can be useful in different scenarios, but I think the most common one is when you have a framework that runs its own node.js dev server and targets Cloudflare for its build output (meaning that in dev you run in node and only the production build is runnable in a worker), in those cases you can use the utility to get a hold of a proxy/simulation of the values you would get in the actual runtime, for example, in Nuxt we have this: https://github.com/pi0/nitro-cloudflare-dev
GitHub
GitHub - pi0/nitro-cloudflare-dev: POC module to enable access to t...
POC module to enable access to the Cloudflare runtime bindings in development server of Nitro and Nuxt - pi0/nitro-cloudflare-dev
Dario
Dario4mo ago
and QwikCity has the following: https://qwik.dev/docs/advanced/vite/#platform which you can pair with getPlatformProxy in this sort of way:
No description
Dario
Dario4mo ago
would be a really neat feature to access the bindings without needing to pass it down all the time.
Yes it definitely would! and we were very close in getting such utility baked-in into the runtime too! https://github.com/cloudflare/workerd/pull/1213 Unfortunately that did not go through (as you can see in the PR's discussion) leaving the user to implement the thing on their own. In the future you should be able to do it using AsyncContext (https://tc39.es/proposal-async-context/). Unfortunately for now the only alternative is to use AsyncLocalStorage (https://nodejs.org/api/async_context.html#class-asynclocalstorage) which works well but requires you to use the nodejs_compat flag (https://developers.cloudflare.com/workers/wrangler/configuration/#use-runtime-apis-directly) Are you familiar with AsyncLocalStorage? or would you like a quick TLDR? (PS: if helpful I could actually whip up a quick library that leverages ALS to implement this sort of getRequestContext utility, I already practically did that in our Next.js adapter: https://github.com/cloudflare/next-on-pages/blob/main/packages/next-on-pages/src/api/getRequestContext.ts)
Dario
Dario4mo ago
PS: I'm adding a warning in our docs specifying that the utility is not to be run in a worker: https://github.com/cloudflare/cloudflare-docs/pull/13065 I hope this can help avoiding future confusion for users, what do you think @piffie?
GitHub
clarify that getPlatformProxy cannot run in workerd by dario-pi...
Add a warning aside to help clarify that getPlatformProxy is a utility designed to run exclusively in Node.js and not workerd I'm adding this warning as it could be beneficial for users based ...
piffie
piffie4mo ago
sounds like a great idea! will look into the asyncStorage. Maybe as a question: why not make a static object holding them? is there a risk that they change (in case the same instance is reused for another request)
Dario
Dario4mo ago
yes using a static object in the global scope has risks of leaking through requests, we indeed always recommend not to put anything in the global scope for that reason (that's one of the main reasons as to why we moved away from the service worker syntax) PS: the leaking should be confined to the same Cloudflare account (meaning, your data can't leak into the worker of another user) One issue with the putting stuff in the global scope is that your worker can in parallel handle multiple requests, so if you were to rely on the global scope things could potentially change mid-request handling
piffie
piffie4mo ago
sure. the global scope would only contain the references to the KV, hyperdrive, d1, etc. But we'll not use it. makes it more consistent.