Taro React + graphql Codegen + urql 客户端实例

Tarojs支持 react/vue, 因此配置 graphql较为简单,以下以 urql 客户端为例

本文涉及的配置文件清单:

文件路径说明
codegen.tsGraphQL Codegen 配置文件
package.json项目依赖和脚本配置
src/app.tsxTaro 应用入口,配置 urql Provider
config/dev.ts开发环境配置,GraphQL 代理服务器
src/schema/home.tsGraphQL 查询语句和类型化 hooks

参考文档

  1. https://nearform.com/open-source/urql/docs/basics/react-preact/
  2. https://nearform.com/open-source/urql/docs/basics/typescript-integration/

安装

精简命令

1
2
npm install --save urql
npm install -D graphql typescript @graphql-codegen/cli @graphql-codegen/client-preset

配置 Codegen 生成客户端代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
// 文件路径:codegen.ts
const config: CodegenConfig = {
  schema: "http://localhost:3000/graphql",
  documents: ["src/schema/*.graphql", "src/schema/*.ts"],
  ignoreNoDocuments: true, // for better experience with the watcher
  generates: {
    "./src/gql/": {
      preset: "client",
      plugins: [],
      config: {
        useTypeImports: true,
      },
    },
  },
}

export default config
1
2
3
4
5
6
// 文件路径:package.json
{
  "scripts": {
    "codegen": "graphql-codegen"
  }
}

配置 urql

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
// 文件路径:src/app.tsx
import { Client, Provider as UrqlProvider, cacheExchange, fetchExchange } from 'urql';

// dev.ts 中配置了 /graphql 代理,生产环境请改为线上 GraphQL 地址,以免出现跨域问题
const client = new Client({
  url: '/graphql',
  exchanges: [cacheExchange, fetchExchange],
});

function App(props: { children: React.ReactNode }) {
// ...
    return <UrqlProvider value={client}>{props.children}</UrqlProvider>;
}

为避免浏览器提供CORS跨域错误,配置 GraphQL 代理服务器

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
// 文件路径:config/dev.ts
// h5部分加入 devServer
// h5: {
    devServer: {
      proxy: {
        '/graphql': {
          target: 'http://localhost:3000',
          changeOrigin: true,
          secure: false,
        },
      },
    },
 // },

GraphQl 调用示例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
// 文件路径:src/schema/home.ts
import { useQuery } from "urql"
import { graphql } from "~/gql"

export const fetchTabs = graphql(`
  query FetchTabs {
    litemallCategory(
      orderBy: { sortOrder: { direction: asc, priority: 10 } }
      where: { level: { eq: "L1" } }
      limit: 8
    ) {
      id
      name
      iconUrl
    }
  }
`)

export function fetchTabList() {
  const [{data}] = useQuery({ query: fetchTabs })

  return data
  // 直接返回数据可以如下,但没有类型:
  // return data?.litemallCategory
}

export const fetchNewGoods = graphql(`
  query FetchNewGoods($limit: Int!, $offset: Int!) {
    litemallGoods(
      orderBy: { sortOrder: { direction: asc, priority: 10 } }
      where: { isOnSale: { eq: true }, isNew: { eq: true } }
      limit: $limit
      offset: $offset
    ) {
      id
      goodsSn
      name
      categoryId
      gallery
      keywords
      brief
      picUrl
      shareUrl
      isNew
      isHot
      unit
      counterPrice
      retailPrice
      detail
    }
  }
`)

export async function fetchNewGoodsList(limit: number, offset: number) {
  const [{data}] = useQuery({
    query: fetchNewGoods, variables: { limit, offset }
  })

  return data
  // 直接返回数据可以如下,但没有类型:
  // return data?.litemallGoods
}

完成

写完 GraphQL语句后,运行 npm codegen,即可在 src/gql/ 下生成相应的类型代码。