taro4.0如何连接graphql

533 阅读2分钟

前言

进了家新公司,他们不用restful,接口全是graphql。这玩意我之前就没用过,官网讲得有点啰嗦,于是找了个学习网站,2h速通crud,上手嘎嘎快。

后来,老大让我去调研下taro,我之前没接触过,觉得这玩意跟uniapp齐名,不至于太拉跨吧。结果我就后悔了。

初始化的坑

跟着官方文档的脚手架去跑react + vite模板,最后发现小程序跑不起来。翻了issue发现这bug一直没人修,最后找到有哥们留言webpack能跑,后来重新拉取webpack模板就行了。

使用v4.0.4脚手架安装 react vite 版本 编译微信小程序报错 #16226

接入apollo/client

接入它也是让我汗流浃背,没有官方支持,另外issue中翻到的成功案例也是18、20年的,也就是说4.0还没有案例。

# taro-apollo发布了 使用graphql的小伙伴们可以来看看哦

但是好在最后捣鼓出来了,有需要的哥们可以参考下。

config配置

config/index.ts

export default defineConfig<'webpack5'>(async (merge, { command, mode }) => {
    const baseConfig: UserConfigExport<'webpack5'> = {
        //...
        mini: {
            webpackChain(chain) {
            
            //  需要自己手动打一个pollyfill,不知道为什么小程序会没有queueMicrotask
            chain.plugin('provide-plugin').use(webpack.ProvidePlugin, [{
              queueMicrotask: [path.resolve(__dirname, 'pollyfill.ts'), 'default']
            }])

            chain.resolve.plugin('tsconfig-paths').use(TsconfigPathsPlugin)

      }
        }
    }
})

config/pollyfill.ts


const queueMicrotask = (callback) => {
  if (typeof window !== 'undefined' && window.queueMicrotask) {
    window.queueMicrotask(callback);
  } else {
    Promise.resolve()
      .then(callback)
      .catch(err => setTimeout(() => {
        throw err;
      }));
  }
};

export default queueMicrotask;

使用方式

App.tsx

import React, { useEffect } from 'react';
import { useDidShow, useDidHide } from '@tarojs/taro';
import Providers from './providers';
// 全局样式
import './app.scss';

function App(props) {
  return props.children;
}

export default function (props) {
  return <Providers>
    <App {...props} />
  </Providers>
};

provider.tsx

import React from 'react';
import { ApolloProvider } from '@apollo/client';
import { client } from '../utils';

export default function Providers({ children }: { children: React.ReactNode }) {
  return <ApolloProvider client={client}>{children}</ApolloProvider>;
} 

uitls

import { ApolloClient, InMemoryCache, createHttpLink } from '@apollo/client';
import { setContext } from '@apollo/client/link/context';
import Taro from '@tarojs/taro';

// 创建自定义 fetch 函数,使用 Taro.request
export function fetch(url: string, init?: RequestInit) {
    const textDecoder = new TextDecoder("utf-8");
    return new Promise<Response>((resolve, reject) => {
        const option: Taro.request.Option<any> = {
            url,
            method: init?.method as "GET" | "POST" | "PUT" | "DELETE" || "GET",
            header: init?.headers,
            data: init?.body,
            responseType: "arraybuffer",
            success: res => {
                resolve({
                    body: res.data,
                    json: () => Promise.resolve(JSON.parse(textDecoder.decode(res.data))),
                    text: () => Promise.resolve(textDecoder.decode(res.data))
                } as Response);
            },
            fail: err => {
                reject(err);
            }
        };

        Taro.request(option);
    });
}

// 创建 HTTP 链接
const httpLink = createHttpLink({
    uri: process.env.TARO_APP_API, // 替换为你的 GraphQL 服务器地址
    fetch: fetch,
    // fetch,
});

// 添加认证头
const authLink = setContext(async (_, { headers }) => {
    // 获取存储的 token(根据你的认证方式调整)
    const token = await Taro.getStorageSync('token');

    return {
        headers: {
            ...headers,
            authorization: token ? `Bearer ${token}` : '',
        }
    };
});

// 创建 Apollo Client 实例
export const client = new ApolloClient({
    link: authLink.concat(httpLink),
    cache: new InMemoryCache(),
    defaultOptions: {
        watchQuery: {
            fetchPolicy: 'network-only',
        },
    },
});

image.png

image.png

image.png

结束

有需要的同学可以自取,有问题可以在评论区留言

github.com/YuinS316/ta…