You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Chrome扩展@apollo/client迁移无法传customFetch调用background.js接口

问题背景

Chrome扩展项目中原先使用apollo-boost导入ApolloClient,通过传入fetch: customFetch参数实现从background.js发起GraphQL API调用。由于apollo-boost已经废弃,迁移到新版Apollo Client过程中遇到异常:

  • 从@apollo/client导入ApolloClient时,找不到传入customFetch函数的配置入口;官方文档仅说明了RESTLink场景下customFetch的配置方式,没有提及GraphQL请求场景的对应配置方法。
  • 按照Apollo官方迁移文档从apollo-client包导入ApolloClient时,配置不生效,甚至完全没有发起API请求。
  • 旧版使用apollo-boost时还会触发Invariant Violation: 29 on react apollo grapql报错,无法定位配置错误点。

迁移后(存在问题的)代码

import { configureStore } from '@koncert/shared-components';
import React from 'react';
import { Provider } from 'react-redux';
import { MemoryRouter as Router } from 'react-router-dom';
import Routes from '../../components/Routes';
// import ApolloClient from 'apollo-client';
import '../../styles/app.scss';
import customFetch from '../../lib/fetch-mp';
// import { InMemoryCache } from 'apollo-cache-inmemory';
import '../../Vendor';
import { TokenProvider } from '../../components/TokenContext';
import ErrorBoundary from '../../components/Common/ErrorBoundary.tsx';
import { ApolloClient, ApolloProvider } from 'apollo-client';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { HttpLink } from 'apollo-link-http';
import { onError } from 'apollo-link-error';
import { ApolloLink } from 'apollo-link';

const client = new ApolloClient({
  link: ApolloLink.from([
    onError(({ graphQLErrors, networkError }) => {
      if (graphQLErrors)
        graphQLErrors.forEach(({ message, locations, path }) =>
          console.log(
            `[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`,
          ),
        );
      if (networkError) console.log(`[Network error]: ${networkError}`);
    }),
    new HttpLink({
      uri: `${process.env.REACT_APP_STORIES_GRAPHQL_URI}`,
      fetch: customFetch,
      credentials: 'same-origin'
    })
  ]),
  cache: new InMemoryCache(),
});

迁移前(apollo-boost版本可运行但有报错)代码

import { ApolloProvider } from '@apollo/react-hooks';
import { configureStore } from '@koncert/shared-components';
import React from 'react';
import { Provider } from 'react-redux';
import { MemoryRouter as Router } from 'react-router-dom';
import Routes from '../../components/Routes';
import ApolloClient from 'apollo-boost';
import '../../styles/app.scss';
import customFetch from '../../lib/fetch-mp';
import { InMemoryCache } from 'apollo-cache-inmemory';
import '../../Vendor';
import { TokenProvider } from '../../components/TokenContext';
import ErrorBoundary from '../../components/Common/ErrorBoundary.tsx';

const client = new ApolloClient({
  uri: `${process.env.REACT_APP_STORIES_GRAPHQL_URI}`,
  fetch: customFetch,
  cache: new InMemoryCache(),
});
问题原因与修复方案

你现在的代码有两个核心问题,直接导致请求发不出去、配置不生效:

  • 导入路径错误:从apollo-client包同时导入ApolloClient和ApolloProvider是完全错误的。apollo-client只包含核心客户端逻辑,ApolloProvider属于React绑定层的导出,旧拆分版本里这个API在@apollo/react-hooks包下,跨包导入不存在的导出会直接导致客户端实例初始化异常,根本走不到发请求的逻辑。
  • 对新版Apollo Client的配置存在误解:GraphQL场景下自定义fetch完全不需要依赖RESTLink,给HttpLink传入fetch参数即可生效。最新版@apollo/client(v3+)已经把HttpLink、InMemoryCache、错误处理链路、React绑定等所有依赖全部内置,不需要单独安装零散的apollo-link、apollo-cache类包。

具体修复步骤

  1. 先清理冗余依赖:把项目里的apollo-boost、apollo-client、apollo-link-http、apollo-link-error、apollo-cache-inmemory、@apollo/react-hooks这些零散的Apollo相关包全部卸载,只保留最新版@apollo/client即可,从根源避免多包版本冲突。
  2. 替换导入和客户端初始化逻辑,代码如下:
// 所有Apollo相关API统一从@apollo/client导入,不需要拆分引入
import {
  ApolloClient,
  ApolloProvider,
  InMemoryCache,
  HttpLink,
  ApolloLink,
  onError
} from '@apollo/client';
import customFetch from '../../lib/fetch-mp';

const client = new ApolloClient({
  link: ApolloLink.from([
    onError(({ graphQLErrors, networkError }) => {
      if (graphQLErrors) {
        graphQLErrors.forEach(({ message, locations, path }) =>
          console.log(`[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`)
        );
      }
      if (networkError) console.log(`[Network error]: ${networkError}`);
    }),
    new HttpLink({
      uri: process.env.REACT_APP_STORIES_GRAPHQL_URI,
      fetch: customFetch, // 此处直接传入自定义fetch,和apollo-boost时期的传参逻辑完全一致
      credentials: 'same-origin'
    })
  ]),
  cache: new InMemoryCache(),
  ssrMode: false, // Chrome扩展环境下关闭SSR检测,避免初始化异常
  connectToDevTools: process.env.NODE_ENV === 'development'
});
  1. 之前遇到的Invariant Violation: 29 on react apollo grapql报错,本质是组件树无法获取到正确的Apollo上下文导致的——基本都是多版本Apollo包冲突、ApolloProvider导入来源错误引发的,把依赖统一收敛到@apollo/client之后这个问题会直接解决。

补充提醒:Chrome扩展的内容脚本存在上下文隔离,如果你的customFetch是要走background.js发起请求,确保customFetch内部的runtime通信逻辑没有被隔离策略拦截,请求头、cookie配置符合扩展的权限声明要求。

内容的提问来源于stack exchange,提问作者Dilip A

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 11:36:21