Skip to content

How to execute code with npm packages for CF workers? #231

@greffgreff

Description

@greffgreff

Hello. I've attempted to execute JS using QuickJS in a cloudflare worker which I have done so successfully with the following inspired by the cloudflare exemple:

import { getQuickJs } from './vm/quickjs';

export default {
	async fetch(request: Request, env: Env): Promise<Response> {
		// Step 1 - Parse URL
		const url = new URL(request.url);
		const pathname = url.pathname.startsWith('/') ? url.pathname.slice(1) : url.pathname;
		if (!pathname) {
			return new Response('No script path provided', { status: 400 });
		}

		// Step 2 - Fetch from KV
		const script = await env.KV.get(pathname);
		if (!script) {
			return new Response(`Script not found: ${pathname}`, { status: 404 });
		}

		// Step 3 - Create VM
		const quickjs = await getQuickJs();
		const rt = quickjs.newRuntime();
		const vm = rt.newContext();

		// Step 4 - Load Script
		const loadResult = vm.evalCode(script);
		if (loadResult.error) {
			return new Response(`Script failed to load: ${vm.dump(loadResult.error)}`, { status: 500 });
		}

		// Step 5 - Run Script
		const runResult = vm.evalCode(`UserScript.handle();`) as any;
		if (runResult.error) {
			return new Response(`Script failed to run: ${vm.dump(runResult.error)}`, { status: 500 });
		}
		const result = vm.dump(runResult.value);

		return new Response(JSON.stringify(result.value));
	},
};

Where script is bundled javascript using esbuild with the following config:

import { build } from "esbuild";
import { promises as fs } from "fs";

try {
  await fs.unlink("dist/bundle.js");
} catch {}

await build({
  entryPoints: ["src/index.js"],
  globalName: "UserScript",
  outfile: "dist/bundle.js",
  platform: "neutral",
  format: "iife",
  bundle: true,
  write: true,
  minify: true,
  treeShaking: true,
});

The above works only if there are no npm packages/web api/node api being used.
My question is: How can I run code with npm packages? I was going to ask in the following issue but thought this could be its own separate issue instead.
I can provide additional clarification if needed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions