Nextjs urql订阅exchange导入问题

Nextjs urql subscription exchange import problem

由于导入问题,我无法让 urql subscriptionsNextJS 一起工作。

基本上我使用的是 urql 文档中推荐的 graphql-ws 库,它需要 ws 实现库(例如:'ws')。当我 import WebSocket from 'ws' 我得到这个错误: Module not found: Can't resolve 'net'

import { createClient, defaultExchanges, subscriptionExchange, Client } from 'urql';
import { createClient as createWSClient } from 'graphql-ws';
import WebSocket from 'ws'; // <-- This causes the error

export const createUrqlClient = (): Client => {
  const wsClient = createWSClient({
    url: 'ws://xxx/graphql',
    webSocketImpl: WebSocket,
  });

  const client = createClient({
    url: 'http://xxx/graphql',
    exchanges: [
      ...defaultExchanges,
      subscriptionExchange({
        forwardSubscription: operation => ({
          subscribe: sink => ({
            unsubscribe: wsClient.subscribe(operation, sink),
          }),
        }),
      }),
    ],
  });

  return client;
};

我尝试了 nextjs 动态导入,但是这两个都不行:

const WebSocket = dynamic(() => import('ws'), { ssr: false });
const WebSocket = dynamic(() => import('ws').then(module => module.default), { ssr: false });

我还尝试更改 next.config.js 中的 webpack 配置以完全不捆绑这些库:

webpack: (config, { isServer }) => {
  if (!isServer) {
    config.resolve.fallback = {
      child_process: false,
      process: false,
      fs: false,
      util: false,
      http: false,
      https: false,
      tls: false,
      net: false,
      crypto: false,
      path: false,
      os: false,
      stream: false,
      zlib: false,
      querystring: false,
      events: false,
      'utf-8-validate': false,
      bufferutil: false,
    };
  }
  return config;
},

但是我得到了这些错误:

./node_modules/ws/lib/validation.js
Module not found: Can't resolve 'utf-8-validate' in '/home/danko/app/node_modules/ws/lib'
warn  - ./node_modules/ws/lib/buffer-util.js
Module not found: Can't resolve 'bufferutil' in '/home/danko/app/node_modules/ws/lib'

如果我也将 'utf-8-validate': falsebufferutil: false 添加到 cfg,我会得到这个错误:

TypeError: Class extends value undefined is not a constructor or null

所以基本上没有什么能正常工作,正如您所看到的...

这有多难,我不是唯一一个将 urql 订阅与 nextjs 一起使用的人,希望有人能帮助我解决这个问题。谢谢!

基本上正如我所想,不需要 impl,因为可以使用原生 html5 websocket,问题是 nextjs 是服务器端的东西。

typeof window !== 'undefined'我几乎不使用那个交换器 这是工作代码:

import { createClient, dedupExchange, cacheExchange, subscriptionExchange, Client, Exchange } from 'urql';
import { multipartFetchExchange } from '@urql/exchange-multipart-fetch';
import { createClient as createWSClient } from 'graphql-ws';

export const createUrqlClient = (): Client => {
  const graphqlEndpoint = process.env!.NEXT_PUBLIC_GRAPHQL_ENDPOINT as string;
  const graphqlWebsocketEndpoint = process.env!.NEXT_PUBLIC_GRAPHQL_WS_ENDPOINT as string;

  let exchanges: Exchange[] | undefined = [dedupExchange, cacheExchange, multipartFetchExchange];

  if (typeof window !== 'undefined') {
    const wsClient = createWSClient({
      url: graphqlWebsocketEndpoint,
    });

    const subExchange = subscriptionExchange({
      forwardSubscription: operation => ({
        subscribe: sink => ({
          unsubscribe: wsClient.subscribe(operation, sink),
        }),
      }),
    });

    exchanges.push(subExchange);
  }

  const client = createClient({
    url: graphqlEndpoint,
    requestPolicy: 'cache-and-network',
    exchanges,
    fetchOptions: () => ({
      credentials: 'include',
    }),
  });

  return client;
};