Nextjs urql订阅exchange导入问题
Nextjs urql subscription exchange import problem
由于导入问题,我无法让 urql subscriptions 与 NextJS
一起工作。
基本上我使用的是 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': false
和 bufferutil: 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;
};
由于导入问题,我无法让 urql subscriptions 与 NextJS
一起工作。
基本上我使用的是 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': false
和 bufferutil: 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;
};