Published on

GraphQL 使用 part1

Authors
  • avatar
    Name
    Jiaqi.Li
    Twitter

基于 Next12、Apollo v3、webpack

依赖版本:


"dependencies": {
"@apollo/client": "^3.7.1",
"graphql": "^16.6.0",
"next": "12.1.6",
"react": "18.2.0",
"react-dom": "18.2.0"
},
"devDependencies": {
"@types/node": "18.11.9",
"@types/react": "18.0.25",
"@types/react-dom": "18.0.8",
"eslint": "8.27.0",
"eslint-config-next": "12.2.4",
"typescript": "4.8.4"
}

开始之前,需要去 Next 官网过一下入门教程(看英文版,中文版过时了),搭建一个简单的博客 APP,了解 Next 的基本使用。

接入 GraphQL

_app.tsx 中:


// import '../styles/globals.css'
import type { AppProps } from 'next/app'
import { ApolloProvider, ApolloClient, InMemoryCache } from '@apollo/client'
const client = new ApolloClient({
uri: 'https://api.github.com/graphql',
cache: new InMemoryCache(),
connectToDevTools: true,
})
function MyApp({ Component, pageProps }: AppProps) {
return (
<ApolloProvider client={client}>
<Component {...pageProps} />
</ApolloProvider>
)
}
export default MyApp

ApolloProvider 组件注入了 client 对象,这样组件中可以使用 useApolloClient 获取 client 实例。

或者直接使用 useQueryuseLazyQuery hook。这都是后话~

webpack 解析 gql 文件

Loading queries with Webpack

TS 识别 gql 文件

这样只能抑制 TS 编译报错,vscode 下 command+左击无法直接跳转到对应语句,有待优化。

根目录新建 types 文件夹(如果没有)


// types/graphql.d.ts
declare module '*.gql'
declare module '*.graphql'

设置 token

准备工作:

  1. Github 申请 token(按文档操作)
  2. 顶级目录创建 local.config.js ,将生成的 token 保存。然后 .gitignore 添加创建的这个文件,避免提交到 Github。

文档地址:

Authentication

Vue 技术栈参考: apollo-vue

文档看起来有点复杂,记录一下具体操作过程。

之前:


const client = new ApolloClient({
uri: 'https://api.github.com/graphql',
cache: new InMemoryCache(),
connectToDevTools: true,
})

现在:


import { token } from '../local.config' // github 生成的 token
const httpLink = createHttpLink({
uri: 'https://api.github.com/graphql',
credentials: 'same-origin',
})
const authLink = setContext((_, { headers }) => ({
headers: {
...headers,
authorization: token ? `Bearer ${token}` : '',
},
}))
const client = new ApolloClient({
cache: new InMemoryCache(),
connectToDevTools: true,
link: authLink.concat(httpLink),
})