在 nextJS 上配置 apollo 客户端以进行订阅的问题
Posted
技术标签:
【中文标题】在 nextJS 上配置 apollo 客户端以进行订阅的问题【英文标题】:Issue configuring apollo client on nextJS for subscriptions 【发布时间】:2020-01-26 05:57:02 【问题描述】:所以,Apollo 客户端用于进行 GraphQL 查询和变异调用,但是当我配置 websocket Link 时,我在浏览器上收到错误:Error: ws does not work in the browser. Browser clients must use the native WebSocket object
。
我确实尝试过关注这篇文章,但没有成功 -> https://github.com/apollographql/subscriptions-transport-ws/issues/333
const isBrowser = typeof window !== 'undefined';
const authLink = setContext((_, headers ) =>
const token = getToken();
console.log('Token', token);
// return the headers to the context so httpLink can read them
return
headers:
...headers,
authorization: token ? `Bearer $token` : "",
);
const wsLink = isBrowser ? new WebSocketLink(
uri: 'ws://127.0.0.1:8080/v1/graphql',
options:
lazy: true,
reconnect: true,
connectionParams: () =>
const token = getToken();
return headers: Authorization: `Bearer $token`
,
webSocketImpl: ws
): null;
const terminatingLink = isBrowser ? split(
( query ) =>
const kind, operation = getMainDefinition(query);
return kind === "OperationDefinition" && operation === "subscription";
,
wsLink,
authLink.concat(httpLink)
): authLink.concat(httpLink);
const link = ApolloLink.from([reportErrors, terminatingLink]);
return new ApolloClient(
connectToDevTools: isBrowser,
s-s-rMode: !isBrowser, // Disables forceFetch on the server (so queries are only run once)
link: link,
cache: new InMemoryCache().restore(initialState || )
);
【问题讨论】:
你看到 nextjs 的 apollo 例子了吗? github.com/zeit/next.js/tree/canary/examples/with-apollo 您设法解决了这个问题吗?我目前正在处理同样的问题。 【参考方案1】:它对我来说很好用。之前的 apollo 版本可以查看@xiao's package
import nextWithApollo from "next-with-apollo";
import
ApolloProvider,
ApolloClient,
ApolloLink,
HttpLink,
split,
from "@apollo/client";
import getDataFromTree from "@apollo/client/react/s-s-r";
import getMainDefinition from "@apollo/client/utilities";
import InMemoryCache from "@apollo/client/cache";
import WebSocketLink from "@apollo/link-ws";
import fetch from "isomorphic-unfetch";
export const withApollo = (
component: Parameters<ReturnType<typeof nextWithApollo>>[0]
): ReturnType<ReturnType<typeof nextWithApollo>> =>
const wsUrl = `ws://localhost:8000/graphql`;
const httpUrl = `http://localhost:8000/graphql`;
if (!httpUrl)
throw new Error(
"either url or httpUrl must be provided to make an apollo connection"
);
const s-s-rMode = !process.browser;
const httpLink: ApolloLink = new HttpLink(
uri: httpUrl,
credentials: "same-origin",
fetch,
);
let link = httpLink;
if (!s-s-rMode && wsUrl)
const wsLink = new WebSocketLink(
uri: wsUrl,
options:
reconnect: true,
,
webSocketImpl: WebSocket,
);
link = split(
( query ) =>
const def = getMainDefinition(query);
return (
def.kind === "OperationDefinition" && def.operation === "subscription"
);
,
wsLink,
httpLink
);
return nextWithApollo(
( initialState ) =>
return new ApolloClient(
link,
s-s-rMode,
connectToDevTools: !s-s-rMode,
cache: new InMemoryCache().restore((initialState as any) || ),
);
,
render: ( Page, props ) => (
<ApolloProvider client=props.apollo>
<Page ...props />
</ApolloProvider>
),
)(component, getDataFromTree );
;
【讨论】:
【参考方案2】:我也遇到了同样的问题,并发了package 来解决它。它支持启用 s-s-r 的查询/变异/订阅。
【讨论】:
以上是关于在 nextJS 上配置 apollo 客户端以进行订阅的问题的主要内容,如果未能解决你的问题,请参考以下文章
如何在客户端 NextJS 中使用 Apollo GraphQL 订阅?
使用 Apollo 客户端在 nextJs 中传递授权标头的最佳方法? ReferenceError: localStorage 未定义
NextJS + Apollo:如何在 getServerSideProps 内的 apolloClient.query 上获取多个查询?