Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for Vercel Edge with Nuxt #180

Closed
cosbgn opened this issue Jun 9, 2023 · 12 comments
Closed

Support for Vercel Edge with Nuxt #180

cosbgn opened this issue Jun 9, 2023 · 12 comments

Comments

@cosbgn
Copy link

cosbgn commented Jun 9, 2023

TypeError: Class extends value #<Object> is not a constructor or null
    at (index.mjs:7:269795)
    at (__nitro:middleware.js:1:17) 

Currently I think the edge runtime is not supported, right?

@vvo
Copy link
Member

vvo commented Jun 9, 2023

Hey @cosbgn, it should be supported. Which package from storage are you using? kv, blob, postgres? Do provide more details (basically how you are using it) and we can help you out. Thanks

@cosbgn
Copy link
Author

cosbgn commented Jun 9, 2023

Hi @vvo This is a small reproduction: https://github.com/cosbgn/edgenu/blob/1e752299099692d875f2bec97edf4ca1c9cc7bdb/server/utils/utils.js use this version as I've tested all sort of libraries to get it to work

@cosbgn
Copy link
Author

cosbgn commented Jun 9, 2023

@cpmooney
Copy link

cpmooney commented Jun 25, 2023

I have been fighting this issue for several days now and would love to understand what the next step is or if there is any kind of workaround. I am using nuxt (created from vercel's provided template). Things I have tried:

  • Vercel postgres and Neon (these might be the same under the hood -- it's not clear to me from documentation).
  • direct connection and pooled connection (I was never able to get direct connection to work even locally, although documentation seems to imply that it should be possible)
  • both createClient and createPool
  • handling env variable implicitly and explicitly

In most cases I am able to connect via localhost and run a simple query but when I deploy to Vercel I hit the error mentioned in the initial post here.

In the current state I am handling the POSTGRES_URL environment variable explicitly and I have confirmed that it's correct in Vercel (by logging it explicitly -- why should I be concerned about security if I cannot connect at all? :) )

Code is very simple.

server/api/data.get.ts

import { createPool } from '@vercel/postgres';

const postgresUrl = useRuntimeConfig().POSTGRES_URL;

const pool = createPool({
  connectionString: postgresUrl,
});

export default defineEventHandler(async (event) => {
  const users = await pool.sql`SELECT * FROM users;`;
  return {
    users: users.rows,
  };
});

Any ideas would be greatly appreciated. There is a group of us who are all really excited about vercel and getting this to work.

@adriancooney
Copy link
Collaborator

@cpmooney can you tell us which version of @vercel/postgres you are using?

@cpmooney
Copy link

Looks like it's the latest version: 0.4.0

@adriancooney
Copy link
Collaborator

@cpmooney I am unable to reproduce your issue unfortunately. I'm on @vercel/postgres@0.4.0 and the following code is working:

import { createPool, sql } from "@vercel/postgres";
import { NextResponse } from "next/server";

const pool = createPool({
  connectionString: process.env.POSTGRES_URL,
});

export const runtime = "edge";

export async function GET() {
  const { rows: sqlDirect } = await sql`SELECT 1 as foobar`;
  const { rows: sqlPool } = await pool.sql`SELECT 1 as foobar`;

  return NextResponse.json({
    sqlDirect,
    sqlPool,
  });
}

And the result I get hitting the endpoint:

$ http https://vercel-storage-playground.vercel.app/api/vercel-storage-issue-180
HTTP/1.1 200 OK
Cache-Control: public, max-age=0, must-revalidate
Connection: keep-alive
Content-Encoding: gzip
Content-Type: application/json
Date: Wed, 28 Jun 2023 08:55:47 GMT
Server: Vercel
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
Transfer-Encoding: chunked
X-Matched-Path: /api/vercel-storage-issue-180
X-Vercel-Cache: MISS
X-Vercel-Id: lhr1::s7ftl-1687942546989-a1bb1e2c5125

{
    "sqlDirect": [
        {
            "foobar": 1
        }
    ],
    "sqlPool": [
        {
            "foobar": 1
        }
    ]
}

And to confirm the function is an edge function:

Screenshot 2023-06-28 at 09 56 30

Can you create an exact reproduction for me to deploy on Vercel?

@cpmooney
Copy link

cpmooney commented Jul 1, 2023

Hi, @adriancooney I spun up a new repo from scratch (from vercel's template) and am hitting the same error. Here is the repo:

https://github.com/cpmooney/nuxt-vercel-example

here is the deployment to vercel:

https://nuxt-vercel-example-1pkfkfbyd-cpmooney.vercel.app/

My neon database just has a single table called users with a single entry. When I run this locally and hit the endpoint I've created I am able to see the entry in the database:

image

but if you click on the link above to see what is deployed, you will see the error. Error in the vercel log is always the same:

TypeError: Class extends value #<Object> is not a constructor or null
    at (index.mjs:1:381410)
    at (__nitro:middleware.js:1:17)

Environment variable POSTGRES_URL was copied from Neon > Dashboard > Connection Details > Pooled connection.

image

Just to confirm that the neon connection is what's causing the issue, here is the deployment for a commit I pushed which does not include the postgres connection. Here is the commit + deployment in case it's helpful to compare:

https://github.com/cpmooney/nuxt-vercel-example/commit/df0d06f70ef486b9f92434793a694ac92e48c59f
https://nuxt-vercel-example-6hvze9gaz-cpmooney.vercel.app/api/data

Let me know if you have any ideas or if this issue belongs elsewhere. I would love to understand what's going on.

Thanks!

  • Chris

@cpmooney
Copy link

cpmooney commented Jul 1, 2023

After digging around a little more I have come to the conclusion that this is just not compatible with nuxt.

@cosbgn
Copy link
Author

cosbgn commented Jul 4, 2023

Also my reproductions at the beginning on this issue are still not working with the same error

@adriancooney adriancooney changed the title Support for Vercel Edge Support for Vercel Edge with Nuxt Jul 4, 2023
@adriancooney
Copy link
Collaborator

adriancooney commented Jul 4, 2023

So it looks like this is a bug with Nuxt and Nitro, Nuxt's build system. The vercel-edge Nitro preset, which builds your Nuxt code for the Vercel Edge environment, does not support the edge-light conditional export of @vercel/postgres. The edge-light export is code specifically designed and built to run in Edge environments. It seems the vercel-edge preset actually doesn't support any packages that export code specific to Edge environments like we do for @vercel/postgres. Nitro thankfully is aware of the problem and have an issue open at nitrojs/nitro#1371.

In the meantime, I've found a workaround using the alias property in your nuxt.config.js:

+import { resolve } from "path";

export default defineNuxtConfig({
  nitro: {
    preset: "vercel-edge",
  },
+  alias: {
+    "@vercel/postgres": resolve(
+      __dirname,
+      "./node_modules/@vercel/postgres/dist/index.js"
+    ),
+  },
  runtimeConfig: {
    POSTGRES_URL: process.env.POSTGRES_URL,
  },
});

We force Nuxt to resolve the Edge compatible entrypoint for @vercel/postgres . I've tested it in the reproduction above and it's confirmed working.

Given that this is a bug in Nuxt/Nitro, I'm going to close this issue out. Folks can use the workaround above or wait for the issue to be fixed in Nitro and upgrade their package - there's not much we can do from this side of the house. Thanks for the report @cosbgn and @cpmooney.

@Hebilicious
Copy link

Hebilicious commented Jul 5, 2023

Thanks for the write-up @adriancooney, this is exactly the case. This is a tricky issue to tackle, because there's no convention about the exports naming resolution.
Yesterday I was looking at libsql and they use http for vercel-edge, web for browser/cfw/netlify edge, and deno for deno ...
I will add the edge-light conditional export, but we could use a standardised naming convention for these things.

In the future feel free to ping me or to open an issue in Nuxt/Nitro so we can propose a solution quicker.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants