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
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
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:
- Ask apollo client authors to publish ESM package with
"type": "module"
field inpackage.json
- Use workarounds in the source code
- 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:
- Switch from experimental modules to
esm
loading mechanism which doesn’t encourage ecosystem to switch to native node ESM from CommonJS. - Create an pull request in Apollo repo and all its dependencies to put
"type": "module"
and put esm entry point to"main"
in thepackage.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.
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));
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(),
});