Typescript compilation error in Node context
Issue Description
Trying to upgrade from 3.4.17 to latest and have started running into this error as of 3.5.0:
index.ts:5:8 - error TS1479: The current file is a CommonJS module whose imports will produce 'require' calls; however, the referenced file is an ECMAScript module and cannot be imported with 'require'. Consider writing a dynamic 'import("@apollo/client")' call instead.
To convert this file to an ECMAScript module, change its file extension to '.mts', or add the field `"type": "module"` to '/project/workspace/package.json'.
5 } from "@apollo/client";
~~~~~~~~~~~~~~~~
I have included a reproduction link. Simply using "module": "NodeNext" in tsconfig.json will cause this. This is the recommended setting for "modern Node.js projects" per the TypeScript documentation. Do you have any recommendations on how to address this? My project is not ESM today.
Link to Reproduction
https://codesandbox.io/p/devbox/recursing-yalow-s8fmpr
Reproduction Steps
Run tsc in the terminal of the repro. Main config setting to set is "module": "NodeNext" in tsconfig.json
@apollo/client version
3.10.4
Hey @chadxz 👋
Thanks for opening this! I'll do my best to take a look at this today. I'm currently working on a reproduction for a potential React bug and I'm on vacation starting tomorrow for the next week. If not me, I'll see if one of the other maintainers has some bandwidth to take a look. Thanks!
Thanks for your patience!
There are two things that look like would get this to work for you. Either you'll need to specify your app with type: "module" in package.json so that you aren't using CommonJS, or you'll need to update your import to ensure you'll getting the CommonJS build. You can do this using the main.cjs path.
import {
ApolloClient,
InMemoryCache,
type NormalizedCacheObject,
} from "@apollo/client/main.cjs";
While this is less than ideal, this should get you what you need for now. We'll be adding proper ESM support in v4 to avoid this issue going forward. Hope this helps!
Thanks for the suggestion @jerelmiller!
I tried this and it looks like that is incompatible with TypeScript as well, unless I'm still missing something:
This is using @apollo/[email protected]
The same is true on the reproduction link:
@chadxz thats...odd. I used your original reproduction and forked it to check. Here is my fork: https://codesandbox.io/p/devbox/gifted-thompson-y875p2?file=%2Findex.ts%3A4%2C8
If you run npx tsc or yarn tsc (pick your favorite) in the terminal, it passes just fine.
Without /main.cjs:
With /main.cjs
Odd that you're still seeing that error in the reproduction 🤔
If you hover over the 3 dots at the beginning of the package name in your screenshot you'll probably see the same message I am seeing.
I can confirm that compiling works fine in the reproduction, but I think that's because it has a minimal tsconfig.json. If you add "strict": true to the tsconfig.json it will spit out the error at compile time.
Also facing this issue, is there any progress?
Adding the .d.ts file for @apollo/core/main.cjs gets rid of TS's complaints, but doesn't feel quite right that it's necessary to do this...
To confirm, this is with module: 'Node16', moduleResolution: 'Node16', strict: true in the tsconfig, where I'm building a library that exposes some logging functionality for consumers, which makes use of the ApolloLink from @apollo/client
+1.
I also have this issue with Node16.
Same issue with NodeNext
+1
you can add your own package.json "type": "module"
I just ran into this. Best I can tell, this is because in the package.json, the types point to the ESM types, and so typescript thinks its importing esm instead of cjs. This was fixed in the server package here, by explicitly shipping cjs types: https://github.com/apollographql/apollo-server/pull/7614
I just run into this. Please fix the types, they are simply wrong. As @HiranmayaGundu correctly said, cjs types are wrong. Consider this tool for more information.
you can add your own package.json "type": "module"
This is not an option for some users. I don't know if asking the user to migrate their whole codebase to ESM is an acceptable workaround. Fixing types should be a matter of emitting CJS types as well.
@notaphplover we are in fact shipping .d.cts files for quite a while now - but it seems we are missing the .d.cts file for main.cjs for some reason.
We'll look into this, but in the meantime it should be possible for you to import from "@apollo/client/core/core.cjs" etc. instead of the main entry point.
@notaphplover The main.d.cts file has been fixed and is now shipping starting with 3.12.11. Hope this helps 🙂
I updated to 3.12.11. I am able to get my app to properly typecheck by changing all my from "@apollo/client" to from "@apollo/client/main.cjs" (and similar for from "@apollo/client/link/retry"). I also needed to update places where I was referring to GraphQLError to instead be GraphQLFormattedError coming out of the client.
I'm not thrilled about having to do this deep import. I don't have to do this with other libraries, and when I do finally get around to migrating my codebase to ESM, it's going to require yet another find/replace to fix this.
At least I can upgrade now. Thanks!
I'm not thrilled about having to do this deep import
We hear you. We will be doing a proper implementation for ESM in 4.0 with support for the exports field among others. I believe we'll still continue to ship CJS as well, but the package should be better setup to handle the more modern tooling.
Glad to hear you can at least upgrade! Thanks for confirming.
@notaphplover The
main.d.ctsfile has been fixed and is now shipping starting with 3.12.11. Hope this helps 🙂
It seems not fixed in 3.12.11
@aramis-it at this point we're going to need a specific example of what you are doing that's not working for you.
Hey @phryneas, I can recreate the issue as well, just write an import in a typescript file and try to compile it targeting commonjs:
import { ApolloClient, InMemoryCache } from "@apollo/client"
export const apolloClient: ApolloClient<unknown> = new ApolloClient({
cache: new InMemoryCache(),
uri: "https://super-duper-graphql-api",
})
The following error should be displayed:
error TS1479: The current file is a CommonJS module whose imports will produce 'require' calls; however, the referenced file is an ECMAScript module and cannot be imported with 'require'. Consider writing a dynamic 'import("@apollo/client")' call instead.
To convert this file to an ECMAScript module, change its file extension to '.mts', or add the field `"type": "module"`
After having a look at the type definitions:
@apollo/client/main.d.cts
export * from "./index.d.ts";
This is wrong. CJS type definitions are different than ESM type definitions the same way CJS modules are different than ESM modules. In order to fix this, you need to compile CJS types instead of exporting ESM ones.
import { ApolloClient, InMemoryCache } from "@apollo/client"
export const apolloClient: ApolloClient
= new ApolloClient({ cache: new InMemoryCache(), uri: "https://super-duper-graphql-api", })
Yes, as previously written in this issue, if you are using CommonJS at this point while relying on Node16 module resolution (and with a bunch of specific bundler configurations), you need to import a real file with a file extension instead of the package name:
-import { ApolloClient, InMemoryCache } from "@apollo/client"
+import { ApolloClient, InMemoryCache } from "@apollo/client/main.cjs"
export const apolloClient: ApolloClient<unknown> = new ApolloClient({
cache: new InMemoryCache(),
uri: "https://super-duper-graphql-api",
})
With 3.12.11, we fixed a bug where other .d.cts were present, but the main.d.cts file was missing.
We get that this is inconvenient, and we will fix that in the next major release, but we cannot change that during the 3.x release as it is a breaking change.
This is wrong. CJS type definitions are different than ESM type definitions the same way CJS modules are different than ESM modules. In order to fix this, you need to compile CJS types instead of exporting ESM ones.
This were true if we were using default exports, but we are not using default exports anywhere in the library. For the artifacts we create, this should be sufficient.
Named export 'useQuery' not found. The requested module '@apollo/client' 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:
node 22, reactjs 19, vite 5.4, typescript 5.7.3
tsconfig:
"target": "ES2022", "module": "ES2022", "moduleResolution": "bundler",
@aramis-it that is a different problem - in your case, please import from @apollo/client/index.js instead of @apollo/client. If that should not solve the problem, please open a new issue so that we can track it separately.
This will be solved in Apollo Client 4.0.
It might still take a while until we're ready to ship (we just released the first alpha, please go over the changelog and try it out!), but the code for this change has already been merged, so I'm going to close this issue.
Do you have any feedback for the maintainers? Please tell us by taking a one-minute survey. Your responses will help us understand Apollo Client usage and allow us to serve you better.
This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. For general questions, we recommend using our Community Forum or Stack Overflow.