ApolloClient is not a constructor (apollo-client with nodejs)

ApolloClient is not a constructor (apollo-client with nodejs)


9

I don’t have any UI framework. Just a simple Nodejs script where I need to query a GraphQL.

Codes:

const ApolloClient = require('apollo-client')
const client = new ApolloClient()

Error message:

TypeError: ApolloClient is not a constructor

Package.json:

{
  ...

  "dependencies": {
    "apollo-client": "^2.4.13",
    "graphql": "^14.1.1",
    "graphql-tag": "^2.10.1"
  },
}

Node: v8.9.4

I googled a while people have this issue mainly because ApolloClient is no longer in react-apollo. You have to import it from 'apollo-client'

And I’m importing from apollo-client as const ApolloClient = require('apollo-client')

Any ideas? Thanks!

0

5 Answers
5


12

If you’re using require, you can import it like this:

const ApolloClient = require('apollo-client').default

or like this

const { ApolloClient } = require('apollo-client')

Otherwise, you’re importing the entire module, which itself is not a constructor.


7

For people who like me using Node require and just want to get it working.

Packages:

npm install graphql apollo-client apollo-cache-inmemory apollo-link-http node-fetch --save

Codes:

const fetch = require('node-fetch')
const { createHttpLink } = require('apollo-link-http')
const { InMemoryCache } = require('apollo-cache-inmemory')
const { ApolloClient } = require('apollo-client')
const gql = require('graphql-tag')

const httpLink = createHttpLink({
  uri: 'https://api.github.com/graphql',
  fetch: fetch
})

const client = new ApolloClient({
  link: httpLink,
  cache: new InMemoryCache()
})

const query = gql`
  query {
    viewer {
      login
    }
  }
`

client.query({
  query
}).catch((error) => {
  console.log(error)
  done()
})

The response is error as you need to add Authorization: bearer YOURTOKEN to request header but that’s another thing.

Thanks to this answer


4

I have a related issue, although using node --experimental-modules, not CommonJS. I’m using apollo-client version 2.6.x and node version 12.x so this might change.

Here’s how I tried to import it:

import { default as ApolloClient } from 'apollo-client';

const client = new ApolloClient();

The reason why it doesn’t work is that --experimental-modules still imports CommonJS version of a given module even though package.json has a "module" field pointing to ESM entry point. It happens because EcmaScript Modules support in Node 12+ relies on either "type" field in package.json or “Michael Jackson script” (.mjs) file extension. And using named import with CommonJS is not supported: https://nodejs.org/api/esm.html#esm_compatibility_with_commonjs_only_versions_of_node_js

So, how to fix? There are two approaches:

  1. Ask apollo client authors to publish ESM package with "type": "module" field in package.json
  2. Use workarounds in the source code
  3. Use esm

Here’s a workaround:

import apolloClient from 'apollo-client';
const { ApolloClient } = apolloClient;

Bonus: full example

import nodeFetch from 'node-fetch';
global.fetch = nodeFetch;
import apolloClient from 'apollo-client';
const { ApolloClient } = apolloClient;
import apolloInMemoryCache from 'apollo-cache-inmemory';
const { InMemoryCache } = apolloInMemoryCache;
import apolloHttpLink from 'apollo-link-http';
const { HttpLink } = apolloHttpLink;

  const cache = new InMemoryCache();
  const link = new HttpLink({
    uri
  });

  const client = new ApolloClient({
    cache,
    link
  });

That’s not very nice. So there are two paths from here:

  1. Switch from experimental modules to esm loading mechanism which doesn’t encourage ecosystem to switch to native node ESM from CommonJS.
  2. Create an pull request in Apollo repo and all its dependencies to put "type": "module" and put esm entry point to "main" in the package.json as a breaking change. Work with maintainers to support temporary compatibility and migration paths. Fork modules and maintain ESM native versions in the meanwhile.


1

We can pass fetch as option for HttpLink and remove global.fetch, here is a full exmaple:

import fetch from 'node-fetch';
import apolloClient from 'apollo-client';
import apolloInMemoryCache from 'apollo-cache-inmemory';
import apolloHttpLink from 'apollo-link-http';
import gql from 'graphql-tag';

const { ApolloClient } = apolloClient;
const { InMemoryCache } = apolloInMemoryCache;
const { HttpLink } = apolloHttpLink;

const uri = 'https://countries.trevorblades.com/';

const link = new HttpLink({ uri, fetch });
const cache = new InMemoryCache();
const client = new ApolloClient({ link, cache });

const query = gql`
  query {
    countries {
      name
    }
  }
`;

client
  .query({ query })
  .then((result) => console.log(result.data));


0

Here’s how I got it to work just using the @apollo/client package. You may not need the HttpLink and fetch stuff – I added that because I was getting this error: fetch error.

import { ApolloProvider } from "@apollo/client/index.js";
import { ApolloClient } from "@apollo/client/core/ApolloClient.js";
import { InMemoryCache } from "@apollo/client/cache/inmemory/inMemoryCache.js";
import { HttpLink } from "@apollo/client/link/http/HttpLink.js";
import fetch from "cross-fetch";

const client = new ApolloClient({
    link: new HttpLink({ uri: "https://localhost:4000/graphql", fetch }),
    cache: new InMemoryCache(),
});



Leave a Reply

Your email address will not be published. Required fields are marked *