-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use zen-observable as ESM #5961
Comments
Here's where we |
The problem is that zen-observable doesn't actually point to its ESM build in its package.json so a bundler can't know that it has one. That package would need to add I wonder if this is also the cause of #5686, although I don't know what would have changed between apollo-boost and @apollo/client to cause this in one but not the other. |
ESM support is a very recent addition to |
There's a use case of apollo-client without a bundler that's worth considering here. Buildless workflows and even smaller applications that use unbundled CDN and http2. I believe post-3.0 ac is moving away from observable, but in the mean time it would be nice to have an all-browser option to cover those use cases. |
Apollo Client currently uses the Observable implementation provided by the zen-observable npm package, since it is small and works well for our needs. Although zen-observable itself is not written in TypeScript, we use the companion package @types/zen-observable to provide types. We are actively considering switching from zen-observable to RxJS (#5749), though it remains to be seen how much of a breaking change that will be (and thus whether it makes sense for a minor or major version update). In the meantime, several issues (most recently #5961) have been opened pointing out that zen-observable effectively does not support importing its code as ECMAScript modules, even though it has a separate entry point (zen-observable/esm.js) that uses ESM syntax. This is a problem the zen-observable package could easily fix by adding a "module" field to its package.json, but @abdonrd tried to propose that change in a PR (as I requested), and has not heard back since June 2020: zenparsing/zen-observable#74 Fortunately, Apollo maintains an npm package called zen-observable-ts, which was originally created to provide TypeScript types, before @types/zen-observable was introduced. This commit revives that wrapper package, so we can make sure both CommonJS and ESM exports are supported, with full TypeScript types, until the zen-observable maintainer gets around to merging that PR. I considered forking zen-observable, but I'm happy with this wrapping strategy, since reusing zen-observable makes it easier to take advantage of any future updates to the zen-observable package. I also considered using https://www.npmjs.com/package/patch-package to apply changes to node_modules/zen-observable/package.json upon installation, but that doesn't really work unless @apollo/client bundles the zen-observable implementation into itself, since otherwise the original (unpatched) zen-observable package will continue to be installed when developers npm install @apollo/client. The patch-package tool is great, but I don't think it's meant for libraries to use. Thankfully, this time around we do not need to hand-write the TypeScript types, since they can be re-exported from @types/zen-observable. I bumped the major version of zen-observable-ts, since the older versions (used by apollo-link) still get more than two million downloads per week. The source code for the zen-observable-ts package can now be found at https://github.com/apollographql/zen-observable-ts, rather than the old https://github.com/apollographql/apollo-link monorepo.
Apollo Client currently uses the Observable implementation provided by the zen-observable npm package, since it is small and works well for our needs. Although zen-observable itself is not written in TypeScript, we use the companion package @types/zen-observable to provide types. We are actively considering switching from zen-observable to RxJS (#5749), though it remains to be seen how much of a breaking change that will be (and thus whether it makes sense for a minor or major version update). In the meantime, several issues (most recently #5961) have been opened pointing out that zen-observable effectively does not support importing its code as ECMAScript modules, even though it has a separate entry point (zen-observable/esm.js) that uses ESM syntax. This is a problem the zen-observable package could easily fix by adding a "module" field to its package.json, but @abdonrd tried to propose that change in a PR (as I requested), and has not heard back since June 2020: zenparsing/zen-observable#74 Fortunately, Apollo maintains an npm package called zen-observable-ts, which was originally created to provide TypeScript types, before @types/zen-observable was introduced. This commit revives that wrapper package, so we can make sure both CommonJS and ESM exports are supported, with full TypeScript types, until the zen-observable maintainer gets around to merging that PR. I considered forking zen-observable, but I'm happy with this wrapping strategy, since reusing zen-observable makes it easier to take advantage of any future updates to the zen-observable package. I also considered using https://www.npmjs.com/package/patch-package to apply changes to node_modules/zen-observable/package.json upon installation, but that doesn't really work unless @apollo/client bundles the zen-observable implementation into itself, since otherwise the original (unpatched) zen-observable package will continue to be installed when developers npm install @apollo/client. The patch-package tool is great, but I don't think it's meant for libraries to use. Thankfully, this time around we do not need to hand-write the TypeScript types, since they can be re-exported from @types/zen-observable. I bumped the major version of zen-observable-ts, since the older versions (used by apollo-link) still get more than two million downloads per week. The source code for the zen-observable-ts package can now be found at https://github.com/apollographql/zen-observable-ts, rather than the old https://github.com/apollographql/apollo-link monorepo.
@abdonrd Thanks for following through and opening that PR! Since there's been no response, I'm moving ahead with a wrapping strategy, using the package name These changes should be released in Apollo Client v3.4 (the next minor version). |
What about finally moving to rxjs, which is a very capable, well maintained and tree shake library ? It is so good that it is already used in Apollo client tests code (!). Moving to rxjs would unify your codebase while reducing bundle size of Angular projects, most likely not increasing React project size. And last but not least it would reduce your maintenance work. I'm more than willing to create a pr for that, if you give me the go. |
I guess the answer to my question is #5749 PS: btw, thanks benjamn for your very informative commit message. I know we don't always feel like taking extra time for that, but yours are an invaluable source of information 🎉 |
Closed by #7615, right? Just |
@abdonrd Yes! However, please note that #7615 is only in the v3.4 betas at this point. Edit: In addition to |
@benjamn yes, looking forward to the release! I'm very glad to read that there will be a solution for "this little package called react". Yeah, little package 😂 |
> Note: I am expecting tests to fail for this commit, demonstrating the importance of using a stable serialization strategy for field arguments. Although fast-json-stable-stringify has done its job well, it only provides a "main" field in its package.json file, pointing to a CommonJS entry point, and does not appear to export any ECMAScript modules. Thanks to our conversion/abandonment of fast-json-stable-stringify and other CommonJS-only npm dependencies (zen-observable in #5961 and graphql-tag in #6074), it should now (after this PR is merged) be possible to load @apollo/client/core from an ESM-aware CDN like jsdelivr.net or jspm.io: <script type=module src="https://cdn.jsdelivr.net/npm/@apollo/client@beta/core/+esm"> </script> If you put that script tag in an HTML file, or inject it into the DOM of any webpage, you will currently see this error: Uncaught SyntaxError: The requested module '/npm/fast-json-stable-stringify@2.1.0/+esm' does not provide an export named 'default' This list of errors used to be longer, but now the only package left is fast-json-stable-stringify. Note that we're loading @apollo/client/core@beta here, not @apollo/client@beta. The reason @apollo/client itself is not yet ESM-ready is that react and react-dom are the two remaining CommonJS-only dependencies, and @apollo/client currently/regrettably re-exports utilities from @apollo/client/react. If importing from @apollo/client/core is a burden or feels weird to you, please know that we are planning to make @apollo/client synonymous with @apollo/client/core in Apollo Client 4.0, along with making @apollo/client/react synonymous with the v3 API of @apollo/client, though of course those will be major breaking changes: #8190
The last version of
zen-observable
has an ESM export:esm.js
.You can also check it at unpkg:
https://unpkg.com/browse/zen-observable@0.8.15/
It would be great that Apollo Client uses that instead of the CJS export (
index.js
).That way,
zen-observable
works directly in the browser.The text was updated successfully, but these errors were encountered: