apollo-client: Missing "exports" property in package.json
Intended outcome: Importing ‘@apollo/client’ into an ES module works.
In my experimenting with a fix, I found https://github.com/antfu/vite-ssg/issues/241 and added the postinstall script to add an exports
property to the package.json
files in the client
and client/core
packages.
The client
package:
"exports": {
".": {
"import": "./index.js",
"require": "./main.cjs",
"types": "./index.d.ts"
},
"./core": {
"import": "./index.js",
"require": "./core.cjs",
"types": "./index.d.ts"
},
"./react": {
"import": "./react/index.js",
"require": "./react/react.cjs",
"types": "./react/index.d.ts"
},
"./react/context": {
"import": "./react/context/index.js",
"require": "./react/context/context.cjs",
"types": "./react/context/index.d.ts"
},
"./*": "./*"
}
The client/core
package:
"exports": {
".": {
"require": "./core.cjs",
"import": "./index.js",
"types": "./index.d.ts"
}
}
Actual outcome: Error from Node.js:
SyntaxError: Named export 'ApolloClient' not found. The requested module '@apollo/client' is a CommonJS module, which may not support all module.exports as named exports.
How to reproduce the issue:
Install Node.js version 18.7.0. Set up a project with "type": "module"
. Install @apollo/client
and import it this way:
import { ApolloClient } from '@apollo/client';
Run Node.
Versions
System:
OS: macOS 12.4
Binaries:
Node: 18.7.0 - ~/.nvm/versions/node/v18.7.0/bin/node
npm: 8.15.0 - ~/.nvm/versions/node/v18.7.0/bin/npm
Browsers:
Chrome: 103.0.5060.134
Safari: 15.5
npmPackages:
@apollo/client: ^3.6.9 => 3.6.9
About this issue
- Original URL
- State: open
- Created 2 years ago
- Reactions: 18
- Comments: 26 (12 by maintainers)
@fernandocanizo I hear you - this is a frustrating experience for everyone involved.
The pragmatic resolution in your case is to add a
/index.js
to every of those imports, which will work without any changes to your bundling and without any package patching.I’ve just confirmed that all of
work fine in Remix.
Perhaps “correct the record” was a poor choice of words on my part so I apologize for that. Just trying to communicate here that we are very aware of this issue and plan to release this in a major version which is coming this year. I’m not oblivious to the fact its been 4 years since the last major release. I definitely hear the frustration on that and understand the sentiment.
To be honest, I’m not sure what “empirical evidence” you’re looking for here. What I can say is that as core maintainer on the library and not simply an observer, I’ve been involved in all the planning meetings and discussions thus far on our releases (at least since I’ve been on the team). The decision not to release a major has nothing to do with a marketing decision but rather our priorities to shipping features in a version that doesn’t also require you to spend significant engineering effort to deal with breaking changes to the library.
In the last year we’ve shipped support for React Suspense, been one of the first libraries to implement compatibility with React Server Components, added optimizations to be more efficient with memory, added query preloading for better compatibility with modern routing libraries, and many other features and improvements that are too long to list here. To say that we are neglecting progress is simply false.
The features listed above have all been community-requested features. To be honest, I’m not entirely sure what you’re looking for here. We’ve got a priority list a mile high and just because we haven’t shipped some requested features doesn’t mean we aren’t shipping them at all or that we are ignoring them.
Its not simply increasing a major version though. A new major version is a signifier that we’ve introduced a breaking change in the library. And with any breaking change, this is engineering time and impact to our users to understand what changed, what the upgrade/migration path is, etc. We want to be thoughtful of any breaking change we introduce to ensure we have a good upgrade path. That requires a lot of planning and thought. If we simply YOLO’d changes into new majors, we’d end up with upgrades that require significant engineering effort, which might mean users stuck on old major versions for a significant amount of time.
For this issue in particular, I’ll reiterate what Lenz said in the PR:
Again, we’ve simply chosen to prioritize shipping new features in the 3.x series of releases where our existing v3 users can enjoy them without having to spend significant engineering effort to upgrade major versions and deal with breaking changes.
Last thing I’ll say is that you seem to be on the defensive here. I apologize if my previous comment came across in a negative way because that is certainly not my intent. I’m definitely not looking to pick a fight here, I simply want to defend the work this team has done because I think we’ve been able to provide a lot of value without having to wait for major versions to do so. Again, I understand the frustration for the long cycle that has been v3 and we are actively working on addressing this.
I hope this helps in some way. Thanks for the response!
Thanks for pointing this out. I filed an issue with the validator so that hopefully we avoid false reports in the future: https://github.com/bluwy/publint/issues/41
Agreed that adding
exports
is a breaking changeI think it’s correct to say that the issues in the validator are not indicative of something being broken. However, the package is still broken when used directly in a Node.js ESM project without bundling as can be seen in the original issue description, so I’m afraid there is still an issue here besides just following the latest trends and practices unfortunately. Understandable that you’d like to group breaking changes together into a new major release though. Is there anywhere to track when a new major might occur? We’ve been getting bug reports about this for a couple years (https://github.com/apollographql/apollo-client/issues/8218), so I’m sure users are eager to see a new major
@jerelmiller I’m sorry for the tone of my message. I am frustrated.
With every single apollo release, we have to re-yarn patch it in three end products plus multiple internal libraries. That is a frustrating experience and it also adds up to a material “engineering effort” that seems like a waste of time when we feel like an ESM release should have already happened some time ago.
What I want (and I’m just one user/org):
In that order. We have an investment in using apollo, as well as many other libraries. There was a critical mass of dependencies using ESM (for us) almost two years ago that required us to switch in order to receive updates to those libraries. Since that time, we have been patching apollo over and over and over again. We have tens (probably more) direct dependencies, which likely extrapolates to a thousand or more in the dependency graph. Apollo is the only dependency we have to patch.
Thank you for the features, but in our case, we would rather have ESM first.
Let me leave off with an apology for my tone, and a sincere thank you for the team’s work. Open source can be thankless, and I do not want to appear to be one of those people. I appreciate the efforts, even if we aren’t necessarily in alignment with how/when decisions should be taken.
Thank you again.
I see from the talk that you’re talking about React Native, and working on a CJS project, however I’m having this issue in an ESM project (a Remix one) by just following the Get started with Apollo Client tutorial.
I’m new to GraphQL and Apollo Client, and this is plain awful developer experience.
These are my minimal set of steps to reproduce:
In
package.json
: (not a step, Remix already provides this, I’m just mentioning for context)Then, after editing
app/root.tsx
and adding what Apollo Client tutorial says:I get:
When searching about this problem I found it happens in several other front-end environments , like Vue and Next.js, so it seems it’s affecting a huge base of projects for roughly 3 years now.
Also, there are other imports affected, that documentation says should be done in a way, but then you hit importing problems. For example:
Also the last example gives me: “error| Could not find a declaration file for module ‘@apollo/client/dev/dev.cjs’” which is an issue I haven’t solved yet.
So my question to @phryneas or anyone that could provide a temporary solution, since this won’t be fixed until v4.0, how can we circumvent these importing problems? Would it be possible to put some work around here and/or maybe mentioning this stuff in the docs?
Is it possible to fix them on my own code via some black magic in
package.json
or whatever? I’d really like to not have to tamper with the installed dependencies viapatch-package
since that would be another step (and possible point of failure) in my project setup.For what it’s worth, I’ve done the following with
patch-package
to add a basicexports
field to@apollo/client
’s `package.json:The
types
field is only required if the type definition file is named differently from the imported/required file.Though this patch won’t work if you import submodules of the client in a node.js CJS environment. If the
@apollo/client
package included their CJS submodule “index” files asindex.cjs
instead of[submodule_folder_name].cjs
, then the patch could be changed to something like the following to support node.js CJS environments:@rafagsiqueira No, the
exports
change needs to wait for a semver major but Apollo hasn’t released a major version in 4 years. My guess is that the team is still approaching major versions as a marketing decision instead of a technical & procedural decision.Maybe take a look at urql which seems really promising.
Why not re-release and bump the major version? It’s not difficult to explain why and there won’t then be compatibility issues.
You can see that the package is broken by checking its validity with publint: https://publint.dev/@apollo/client@3.7.14