Nextjs urql订阅交换导入问题



由于导入问题,我无法让urql订阅与NextJS一起工作。

基本上我正在使用这个graphql-ws库,这是在urql文档中推荐的,需要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 });

我也试图改变webpack配置在next.config.js不捆绑这些库:

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;
};

@dankobgd

我有同样的问题,你的回答帮助了我。我简化了一下,它可以工作了

export const client = (): Client => {
let exchanges: Exchange[] = [...defaultExchanges]
if (typeof window !== 'undefined') {
const wsClient = createWSClient({
url: wsUrl,
})
const subExchange = subscriptionExchange({
forwardSubscription: (operation) => ({
subscribe: (sink) => ({
unsubscribe: wsClient.subscribe(operation, sink),
}),
}),
})
exchanges.push(subExchange)
}
return createClient({
url,
exchanges,
})
}

最新更新