Skip to content
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

@apollo/client requires React to be installed when using @graphql-tools/links #4901

Closed
2 of 4 tasks
vtereshyn opened this issue Dec 13, 2022 · 6 comments
Closed
2 of 4 tasks

Comments

@vtereshyn
Copy link

vtereshyn commented Dec 13, 2022

Issue workflow progress

Progress of the issue based on the Contributor Workflow

  • 1. The issue provides a reproduction available on Github, Stackblitz or CodeSandbox

    Make sure to fork this template and run yarn generate in the terminal.

    Please make sure the GraphQL Tools package versions under package.json matches yours.

  • 2. A failing test has been provided
  • 3. A local solution has been provided
  • 4. A pull request is pending review

Describe the bug

When using @graphql-tools/links it requires installing react as a dependency. My server package doesn't need react. This happens because when @apollo/client is imported like import * as apolloClient from '@apollo/client, it also imports modules that require React. To avoid that, the proper input should be import ... from '@apollo/client/core'. That is taken from @apollo/client issue – apollographql/apollo-client#7318 (comment)

To Reproduce
Steps to reproduce the behavior:

https://codesandbox.io/s/heuristic-morning-zm76mw?file=/src/index.ts

Expected behavior

It shouldn't require react in server modules that are not using react and related functionality. Adding react as a dependency works as a workaround, but this is not how it should be IMO.

Environment:

  • OS: Mac OS Monterey 12.6.1
  • @graphql-tools/...: links - 8.3.24
  • NodeJS: 18.12.0
@tal130
Copy link

tal130 commented Jan 2, 2023

@ardatan any update on this?

@ardatan
Copy link
Owner

ardatan commented Jan 2, 2023

If we use deep imports, ESM doesn't work properly because Apollo Client doesn't implement ESM properly. If anyone has a solution that uses deep imports with ESM support, PRs are welcome. And of course this needs to be tested properly.

@yusufkandemir
Copy link

Duplicate of #4582

@yusufkandemir
Copy link

Normally, @apollo/client/core entry-point would work fine and point to the ESM, CJS, and types variants correctly. But, Apollo Client doesn't specify the exports configuration. It seems they decided to leave it to Apollo Client v4 (apollographql/apollo-client#9697), which doesn't even have an ETA yet. Also, it would take some time for the ecosystem to catch up after the v4 release. So, basically, waiting for a fix on their side will take forever.

Deep imports examples:

  • ESM: @apollo/client/core/index.js
  • CJS: @apollo/client/core/core.cjs

So, technically, it's possible to make both ESM and CJS work without importing the whole package. That would avoid the React dependency problem. However, Bob the Bundler seems to do transpilation using TSC and doesn't allow much further modification(which is understandable given its current use cases). It doesn't support creating multi-variant source files either (index.ts + index.cts). So, with the current tooling, it doesn't seem possible to achieve this either. If the team is willing to update their tooling to allow this somehow, it would be great.

Other than these two options, I see two alternative "solutions":

  1. Move away from Apollo Client to another client, similar to moving away from Apollo Server to GraphQL Yoga.
  2. Use tools like pnpm patch/yarn patch to patch the affected packages @graphql-tools/links and @graphql-tools/executor-apollo-link to use the corresponding ESM/CJS deep imports as I have shown above. Here is an example with pnpm:
    patches/@graphql-tools__executor-apollo-link@0.0.6.patch:
diff --git a/cjs/index.js b/cjs/index.js
index 8dbdfe0837090bf2c55c2d7369b6f7ecb408402f..ab18d21d83f77da0ef93864a10463f2de571766c 100644
--- a/cjs/index.js
+++ b/cjs/index.js
@@ -1,14 +1,11 @@
 "use strict";
-var _a;
 Object.defineProperty(exports, "__esModule", { value: true });
 exports.ExecutorLink = void 0;
-const tslib_1 = require("tslib");
-const apolloImport = tslib_1.__importStar(require("@apollo/client"));
+const { ApolloLink, Observable } = require("@apollo/client/core/core.cjs");
 const utils_1 = require("@graphql-tools/utils");
-const apollo = (_a = apolloImport === null || apolloImport === void 0 ? void 0 : apolloImport.default) !== null && _a !== void 0 ? _a : apolloImport;
 function createApolloRequestHandler(executor) {
     return function ApolloRequestHandler(operation) {
-        return new apollo.Observable(observer => {
+        return new Observable(observer => {
             const executionRequest = {
                 document: operation.query,
                 variables: operation.variables,
@@ -40,7 +37,7 @@ function createApolloRequestHandler(executor) {
         });
     };
 }
-class ExecutorLink extends apollo.ApolloLink {
+class ExecutorLink extends ApolloLink {
     constructor(executor) {
         super(createApolloRequestHandler(executor));
     }
diff --git a/esm/index.js b/esm/index.js
index 8667c5ca9b135b88be2b387284875b66e75d9a93..d4a54383fc2131ade7be71507bc0c14760d80db2 100644
--- a/esm/index.js
+++ b/esm/index.js
@@ -1,10 +1,8 @@
-var _a;
-import * as apolloImport from '@apollo/client';
+import { ApolloLink, Observable } from "@apollo/client/core/index.js";
 import { isAsyncIterable } from '@graphql-tools/utils';
-const apollo = (_a = apolloImport === null || apolloImport === void 0 ? void 0 : apolloImport.default) !== null && _a !== void 0 ? _a : apolloImport;
 function createApolloRequestHandler(executor) {
     return function ApolloRequestHandler(operation) {
-        return new apollo.Observable(observer => {
+        return new Observable(observer => {
             const executionRequest = {
                 document: operation.query,
                 variables: operation.variables,
@@ -36,7 +34,7 @@ function createApolloRequestHandler(executor) {
         });
     };
 }
-export class ExecutorLink extends apollo.ApolloLink {
+export class ExecutorLink extends ApolloLink {
     constructor(executor) {
         super(createApolloRequestHandler(executor));
     }

Root package.json:

  "pnpm": {
    "patchedDependencies": {
      "@graphql-tools/executor-apollo-link@0.0.6": "patches/@graphql-tools__executor-apollo-link@0.0.6.patch"
    }
  }

(or fully follow the regular patch process and make the changes yourself, start by executing pnpm patch @graphql-tools/executor-apollo-link@0.0.6)

@n1ru4l
Copy link
Collaborator

n1ru4l commented Feb 14, 2023

Thank you @yusufkandemir for the great summary and documentation of possible workarounds. We are open to contributions in bob-the-bundler that allow working around this kind of limitation.

@n1ru4l
Copy link
Collaborator

n1ru4l commented Feb 14, 2023

In the meantime, I am closing this issue as it is a duplicate of #4582.

@n1ru4l n1ru4l closed this as completed Feb 14, 2023
Repository owner locked as resolved and limited conversation to collaborators Feb 14, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants