Edge function with npm dependency behaves erratically on development environments and doesn't work on production
Bug report
Running deno code that loads JavaScript modules via the deno provided require wrapper doesn't work on the hosted environments but sort of works locally. "Sort of" because it crashes if enabled on boot, but it works fine after hot reload. So this bug report is fundamentally about two things:
- The development environment behaves differently on boot (crash) and after hot reload (works fine)
- Neither the development environment nor the production environment allow me to work with existing code that relies on
npmdependencies
I'm sorry for the lengthy report, it really took me a while to understand that the root of the different behavior is the hot reloading. I assume I'm doing something that's unsupported, but I would really appreciate it if this at least would fail fast and consistently.
To Reproduce
Steps are explained in a example repository: https://github.com/MarcusRiemer/supabase-npm-edge-functions
I basically compile TypeScript project called npm-lib with a single dependency (immer) to JavaScript and load it using the following deno typescript file:
// server/supabase/functions/core-data.ts
import { createRequire } from "https://deno.land/[email protected]/node/module.ts";
const require = createRequire(import.meta.url);
export const core_data = require("./npm-lib");
console.log("Hello from core data", core_data);
I then use this module in a edge function:
// server/supabase/functions/hello-npm/index.ts
import { serve } from "https://deno.land/[email protected]/http/server.ts"
// ### Uncomment after boot ###
//import { core_data } from "../core-data.ts"
//console.log("Hello from Functions, core data is ", core_data.CORE_DATA)
serve(async (req) => {
const { name } = await req.json()
let data = name;
// ### Uncomment after boot ###
//data = core_data.update(name);
return new Response(
JSON.stringify(data),
{ headers: { "Content-Type": "application/json" } },
)
})
Expected behavior
The code in the library (and the immer dependency) are loaded, so that the log output reads as follows:
Hello from core data { CORE_DATA: { foo: [ 1, 2, 3 ] }, update: [Function: update] }
Hello from Functions, core data is { foo: [ 1, 2, 3 ] }
Additonally requests should be answered with a { foo: $NAME } response depending on the argument given when invoking the function.
Actual behavior
The function fails to boot if the marked lines are executed. The errors read something along the lines of the following:
TS2339 [ERROR]: Property 'loadavg' does not exist on type 'typeof Deno'. 'Deno.loadavg' is an unstable API. Did you forget to run with the '--unstable' flag?
return Deno.loadavg();
~~~~~~~
at https://deno.land/[email protected]/node/os.ts:171:15
If the lines are commented out after boot, the function works flawlessly though.
On production I get ReferenceError: Cannot access 'NodeTypeError' before initialization at file:///src/main.ts:4730:36. I checked the output of deno bundle and it simply omits the package.json and npm-lib content.
System information
- OS: Arch Linux
- Version of supabase: 1.7.0
- Version of Node.js: v16.16.0
Additional context
My existing TypeScript library is almost free of npm dependencies (save for immer) and must work in a browser context as well. So this was my (failed) attempt to re-use the library in an edge function.