How can I enable support for `eval()` in Workers?
Yes yes I know all the caveats about
eval()
but it's essential for my use-case. When running in dev mode (but with --remote
i.e. running on CF architecture) I get:
I've read this but didn't fully understand what to action from it. Could someone please advise? Thank you!29 Replies
You can't enable it. Workers running on Cloudflare's network cannot eval. Perhaps #workers-for-platforms could work for you?
If you're fine with the workers running locally, you can enable eval in workers on workerd.
Oh dang... I've spent 3 weeks converting our app to serverless/CF and I'm completely screwed if I can't get eval to work.
Could you please elaborate on WfP? I'm unfamiliar with that or how it differs from plain old Workers that I'm currently using. I'm afraid I also don't understand your second paragraph - I'm quite new to the serverless/CF world.
Thank you
What do you need eval for?
WfP is an (mostly enterprise-only, though not entirely) feature that lets you upload workers and call them dynamically. It's intended to be used for letting your users write and upload code that does something on your website. For more info see https://developers.cloudflare.com/cloudflare-for-platforms/workers-for-platforms/
To clarify, it's not literally
eval()
I'm using but the new Function()
constructor which I suppose is eval()
via another name (I know there are some scoping differences.)
We have a system where users build automations. We have a UI for this and their automations are saved in proprietary (i.e. pseudo) code. I then have a parser that turns this code into valid JS, which is then fed to the func construc.
WfP sounds a little nuclear and complex for what we need so it would be great if there were any way around this other than that.There really isn't. If you want the code to run in workers on Cloudflare's network, you can't use
eval
(or similar). I think WfP would fit quite well with that use-case, but of course the enterprise nature of it makes that a tough pill to swallow. The alternative would be to run the user code somewhere else, or create a worker yourself from the user's code and run that. The latter has major downsides, biggest of which is that the number of workers is limited to 500, which means a maximum of 500 different JS scripts.Ah dang. Well, I appreciate the advice all the same. I'll have to give it some thought. Would another option be to write a physical JS file that can then be imported and read, rather than evaluating strings of JS?
Do have a look at this: https://discord.com/channels/595317990191398933/1012440514135593083/1103682164870103130
It isn't entirely enterprise only, but added on a case-by-case basis
That would still require (bundling it and) uploading it to a worker. You can't dynamically write files and import them in the worker itself
Ah OK fair enough. When you say tough pill to swallow, presumably that's re: the higher costs? And would this no-eval limitation be true of serverless in general or just CF Workers, do you suppose?
Yea higher costs, especially if you need to get Ent, that starts at several thousands of dollars a month. Hopefully you'll be able to get it on paygo though! And, as you already noted, it will require at least some architectural changes for you.
I think it depends on the way the serverless is implemented. A lot of serverless providers give you a full VM that is started when it is requested, which means you can do basically anything you want. Workers are very different, they only spin up a V8 isolate for you, which is much cheaper and faster, but also provides less of a boundary between your code and other people's code (and data). Therefore, workers have a rather strict safety model (https://developers.cloudflare.com/workers/reference/security-model/), which includes making sure all code executed on the platform can be audited by CF employees if you are attacking the platform. Eval doesn't allow this. See https://github.com/cloudflare/workerd/discussions/1432#discussioncomment-7644428
Ah OK that makes sense. Just finally, could I ask you to clarify what you mean by "If you're fine with the workers running locally, you can enable eval in workers on workerd."
Does that pertain to WfP, or Workers?
Just found this thread which says eval is "available via a binding". Does that have any significance to what I'm trying to do?
Really appreciate your help, BTW.
Those last two are related: The workers runtime, workerd, can be run locally. That's also what miniflare (which is in turn used by wrangler) uses to run your development workers locally. In the local version of the runtime, you can use eval via that binding, but that would only run on your own server(s), not on Cloudflare's network.
Ahhhh right.
Just to clarify: you meant earlier that I wouldn't be able to
fp.write
a file and then import it within the same runtime?Correct, all files must be bundled at deploy time
Yea that, and workers also don't have a file system. There wouldn't even really be a place to write a file to 😅
Given @kian's reply I guess the answer here will be no, but I assume I couldn't use a Node loader to load modules from remote sources? Not eval'd code exactly, but not bundled either...
The only way you can really have unbundled code evaluated is running a JS engine in WASM
which isn’t ideal
eval, new Function, URL imports, WASM from a buffer, etc - none of them will work in Workers
WASM - not sure what this but can check it out but I note that you say it's not ideal, whatever it is!
WebAssembly - native languages like C or Rust can compile to it and then you can run that in Workers
Of course, without a lot of plumbing, it tends to be pretty basic (you’re not going to be able to access Workers runtime APIs without connecting them all up)
Twitter
vxTwitter / fixvx
Kian (@Kian_NH)
Turns out you can use the @boa_engine JavaScript Engine on @Cloudflare Workers
This example comes out to 1,224 KiB - which is below the 5 MiB limit of the Workers paid plan!
💖 45 🔁 11
I’ve used Boa before but I’m pretty sure someone else got QuickJS or JSC working
This works with some hacking to get it working on Workers, Boa Just Works™️
Ah so you can use WASM to run JS, or am I misunderstanding? Anyway I'll go read your links as a starting point - thank you.
Kind of - you compile a JavaScript engine, like the very one that Workers is running on (V8, except that probably won't work) and then you can use that.
It's a pretty overengineered/overkill
eval
Thanks, I'll do some digging
Yeah - sounds like using a nuclear bomb to smash a window, but perhaps my only hope.
It depends what you're trying to
eval
fetch, using KV, HTMLRewriter, etc? probably going to be a lot of work
just basic/ECMA JS features? fineI found this as a seemingly simple way to safe-eval JS via WASM, @kian : https://github.com/maple3142/wasm-jseval?tab=readme-ov-file#usage
Does it look like that would do the trick?
Leo - the pseudo code is our own invention, proprietary code. So there is no emulator. My parser RegExps it to valid JS.
Oh it's hacky AF, but it works a treat. Anyway that's kind of academic for my current issue.
Depends if it works in Workers
Lots of them assume a browser environment and need lots of hacking together to avoid that
Dang. Oh well, at least there's a glimmer of hope, if I can find a WASM JS safe-eval tool like this that supports Node/Workers and a later ES. What specifically would identify one as bring Workers compat, and is the general idea here at least sound?
Cool I'll give it a go. Only question then is whether I can adapt the JS to satisfy the ES constraints.
Ha, doesn't work - throws an error from deep in the module's source code. Hey ho.