fauna / faunadb-js

Javascript driver for Fauna v4 (deprecated)
https://docs.fauna.com/fauna/v4/
Other
702 stars 75 forks source link

TypeError: faunadb.Client is not a constructor #668

Open pieterdd opened 1 year ago

pieterdd commented 1 year ago

I'm trying to use faunadb in a codebase that uses ES Module syntax and I get this:

TypeError: faunadb.Client is not a constructor

Curiously, this happens when a Vite-powered SvelteKit codebase is deployed on Netlify/Vercel, but works without issue on my local machine. This is my import line:

import * as faunadb from 'faunadb';

I constructed the object like this:

new faunadb.Client({
    secret: FAUNA_API_KEY,
    domain: 'db.us.fauna.com',
});
github-actions[bot] commented 1 year ago

Internal ticket number is FE-2896

henryfauna commented 1 year ago

Hi @pieterdd, sorry you ran into this. Do any of the following work for you?

import { Client } from 'faunadb'
new Client({
    secret: FAUNA_API_KEY,
    domain: 'db.us.fauna.com',
});
import faunadb from 'faunadb'
new faunadb.Client({
    secret: FAUNA_API_KEY,
    domain: 'db.us.fauna.com',
});
pieterdd commented 1 year ago

Hi Henry, thanks for helping me diagnose this issue. The first approach works on my local development server but yields the following error when deployed:

import { Client, query } from "faunadb";
         ^^^^^^
SyntaxError: Named export 'Client' not found. The requested module 'faunadb' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:

import pkg from 'faunadb';
const { Client, query } = pkg;

The second approach, which is also in line with what the error suggests, does not get accepted by TypeScript on my machine. The error reads:

Module '"[path to my code]/node_modules/faunadb/index"' has no default export.ts(1192)
index.d.ts(1, 1): 'export *' does not re-export a default.
ptpaterson commented 1 year ago

Hi @pieterdd have you figured this out? I acknowledge it has been quite some time since you created the issue.

Have you tried setting the following in your tsconfig.json file?

    "esModuleInterop": true,
    "moduleResolution":"node",
pieterdd commented 1 year ago

I haven't, so I added the lines to tsconfig.json. After deploying it this is still popping up in the logs:

TypeError: faunadb.Client is not a constructor

pieterdd commented 1 year ago

FWIW, I bumped into https://github.com/vitejs/vite/issues/4680. It looks like CommonJS modules and Vite (@rollup/plugin-commonjs) don't mix very well. The thread tracks with my earlier observation that it only occurs on my production builds.

vxern commented 1 year ago

Are there any updates on this? Importing the library into an ESM project still errors.

  "dependencies": {
    "fauna": "npm:faunadb@^4.8.0"
  }
import * as Fauna from "fauna";
client: new Fauna.Client({
    secret: process.env.FAUNA_SECRET!,
    domain: "db.us.fauna.com",
    scheme: "https",
    port: 443,
}),
TypeError: Fauna.Client is not a constructor
    at createDatabase (c:\Users\Administrator\Documents\Programming\Projects\Private\logos\src\lib\database\database.ts:251:11)
    at createClient (c:\Users\Administrator\Documents\Programming\Projects\Private\logos\src\lib\client.ts:145:13)
    at initialiseClient (c:\Users\Administrator\Documents\Programming\Projects\Private\logos\src\lib\client.ts:168:17)
    at initialise (c:\Users\Administrator\Documents\Programming\Projects\Private\logos\src\initialise.ts:185:9)
sumerokr commented 1 year ago

I use fauna with Cloudflare pages, therefore I have a /functions folder on root level of my project. Had the same issue, but able to solve it with

// /functions/tsconfig.json
{
  "compilerOptions": {
    "target": "esnext",
    "module": "esnext",
    "lib": ["esnext"],
    "types": ["@cloudflare/workers-types"],
    "moduleResolution": "Node" // THIS LINE ADDED
  }
}

And here is how I use fauna within my edge functions

import { Client, Ref, Collection, Get } from 'faunadb';

interface Env {
  FAUNA_DB_KEY: string;
}

export const onRequestGet: PagesFunction<Env> = async ({ request, env }) => {
  const faunaClient = new Client({
    secret: env.FAUNA_DB_KEY,
  });

  const url = new URL(request.url);
  const id = url.pathname.split('/').pop();

  const response: any = await faunaClient.query(Get(Ref(Collection('customers'), id)));

  return new Response(JSON.stringify(response));
};

Hope this could help someone.

barancev commented 9 months ago

Is there a known workaround to use Client class in an ESM module?

electrovir commented 7 months ago

I got this to work in ESM code by using import faunadb from 'faunadb' as my import.