Apollo GraphQL:GraphQLWsLink(订阅)问题。无法使 WebSocket 实现在 Next.js 下工作

Apollo GraphQL: GraphQLWsLink (Subscriptions) Troubles. Cannot get WebSocket implementation to work w/ Next.js

所以我有一个用 Go 编写的 GraphQL 服务器,在 this tutorial pretty closely. I have my front-end written as a Next.js application, and I am currently trying to create a client to connect to my server and even following the subscription docs 到 T 之后,我似乎无法让它工作。为什么提供的示例不包含 webSocketImpl

如果我不提供 webSocketImpl,我会得到:

Error: WebSocket implementation missing; on Node you can `import WebSocket from 'ws';` and pass `webSocketImpl: WebSocket` to `createClient`

所以,自然地,我 import { WebSocket } from "ws"; ,并且有:

const wsLink = new GraphQLWsLink(
    createClient({
        webSocketImpl: WebSocket,
        url: "ws://localhost:8080/subscriptions",
    })
);

然后我在哪里得到:

error - ./node_modules/node-gyp-build/index.js:1:0
Module not found: Can't resolve 'fs'

这是完整的代码,基本上我只需要创建一个 ApolloClient 并将其导出以用于我的 React 代码。

import { ApolloClient, HttpLink, InMemoryCache, split } from "@apollo/client";
import { GraphQLWsLink } from "@apollo/client/link/subscriptions";
import { createClient } from "graphql-ws";
import { getMainDefinition } from "@apollo/client/utilities";
import { WebSocket } from "ws";

const wsLink = new GraphQLWsLink(
    createClient({
        webSocketImpl: WebSocket,
        url: "ws://localhost:8080/subscriptions",
    })
);

const httpLink = new HttpLink({
    uri: `http://localhost:8080/query`,
});

const link = split(
    ({ query }) => {
        const def = getMainDefinition(query);
        return (
            def.kind === "OperationDefinition" && def.operation === "subscription"
        );
    },
    wsLink,
    httpLink
);

export const Client = new ApolloClient({
    link,
    cache: new InMemoryCache(),
});

我是不是完全漏掉了什么?我的安装中没有默认的 WebSocket 实现吗?显然 "ws" 实现并没有削减它,可能是因为 fs 在浏览器中不可用?

我在这里遗漏了一件重要的事情:我正在使用 Next.js。发生这种情况的原因是 SSR。基本上,如果我们在浏览器中使用 `typeof window !== 'undefined',我们只需要生成 WebSocket link。这是我更新的代码:

import { ApolloClient, HttpLink, InMemoryCache, split } from "@apollo/client";
import { GraphQLWsLink } from "@apollo/client/link/subscriptions";
import { createClient } from "graphql-ws";
import { getMainDefinition } from "@apollo/client/utilities";

const wsLink =
    typeof window !== "undefined"
        ? new GraphQLWsLink(
                createClient({
                    url: "ws://localhost:8080/subscriptions",
                })
          )
        : null;

const httpLink = new HttpLink({
    uri: `http://localhost:8080/query`,
});

const link =
    typeof window !== "undefined" && wsLink != null
        ? split(
                ({ query }) => {
                    const def = getMainDefinition(query);
                    return (
                        def.kind === "OperationDefinition" &&
                        def.operation === "subscription"
                    );
                },
                wsLink,
                httpLink
          )
        : httpLink;

export const client = new ApolloClient({
    link,
    cache: new InMemoryCache(),
});