urql
高度可扩展且轻量级的 GraphQL 客户端
urql(universal React QL)是一个高度可定制、轻量级的 GraphQL 客户端,核心创新在于 Exchange 交换器架构——一种函数式管道中间件机制。支持 React/Preact/Vue/Solid/Svelte 多框架,核心包 gzip 约 10-12 KB,远小于 Apollo Client。GitHub 约 9,000 Stars,是 GraphQL 生态中最轻量的客户端之一。
urql
高度可扩展且轻量级的 GraphQL 客户端
技术简介说明
urql(全称 "universal React QL")是一个高度可定制、轻量级的 GraphQL 客户端,由 Formidable 团队创建,目前由 urql-graphql 团队持续维护。它的设计哲学是"渐进式复杂度"——你可以从一个极简的 GraphQL 客户端开始,仅在需要时才引入高级功能(如规范化缓存),而非被迫接受一个庞大而复杂的全能方案。这种设计理念使其成为 GraphQL 生态中最轻量、最灵活的客户端之一。
urql 的核心创新在于其 Exchange(交换器)架构——一种类似中间件的管道机制,所有 GraphQL 操作都经过一系列可组合的 Exchange 进行处理。这种设计让开发者可以精确控制请求的去重、缓存、重试、鉴权、日志等各个环节,甚至可以在不修改核心代码的情况下完全改变客户端的行为。相比 Apollo Client 的 Link 机制,urql 的 Exchange 提供了更强的函数式组合能力和更低的运行时开销。
urql 是一个真正的多框架客户端,通过单一核心包 @urql/core 为 React、Preact、Vue、Solid 和 Svelte 提供官方绑定。这意味着团队可以在不同框架之间共享同一套 GraphQL 逻辑和缓存策略,而无需为每个框架引入不同的客户端库。截至 2026 年 7 月,urql 的 React 主包已更新至 5.0.3 版本,核心包 @urql/core 已更新至 6.0.3 版本,持续活跃发展。
基本信息
| 项目 | 内容 |
|---|---|
| 官网 | https://urql.dev |
| 文档 | https://nearform.com/open-source/urql/ |
| GitHub | https://github.com/urql-graphql/urql |
| License | MIT |
最新版本(React 主包 urql) | 5.0.3(2026 年 7 月) |
最新版本(核心包 @urql/core) | 6.0.3(2026 年 7 月) |
| GitHub Stars | ~9,000 |
| 主要语言 | TypeScript(约 90%) |
| 维护者 | urql-graphql 团队(原 Formidable Labs) |
| 框架支持 | React、Preact、Vue、Solid、Svelte |
| 包管理 | npm / pnpm / yarn |
快速上手
安装
根据你使用的框架选择对应的包:
# React
npm install urql @urql/core graphql
# Preact
npm install @urql/preact @urql/core graphql
# Vue
npm install @urql/vue @urql/core graphql
# Solid
npm install @urql/solid @urql/core graphql
# Svelte
npm install @urql/svelte @urql/core graphql
# 规范化缓存(可选,所有框架通用)
npm install @urql/exchange-graphcache使用 pnpm:
pnpm add urql @urql/core graphql
pnpm add @urql/exchange-graphcache # 可选基础配置
React 示例
import { createClient, Provider } from 'urql'
const client = createClient({
url: 'https://api.example.com/graphql',
// 可选:配置 exchanges
// exchanges: [dedupExchange, cacheExchange, fetchExchange]
})
function App() {
return (
<Provider value={client}>
<YourApp />
</Provider>
)
}Vue 示例
import { createClient, installUrql } from '@urql/vue'
const client = createClient({
url: 'https://api.example.com/graphql',
})
const app = createApp(App)
app.use(installUrql, client)最小示例
import { useQuery, gql } from 'urql'
const TodosQuery = gql`
query Todos {
todos {
id
title
}
}
`
function Todos() {
const [result] = useQuery({ query: TodosQuery })
if (result.fetching) return <p>加载中...</p>
if (result.error) return <p>出错了:{result.error.message}</p>
return (
<ul>
{result.data?.todos.map((todo) => (
<li key={todo.id}>{todo.title}</li>
))}
</ul>
)
}核心概念与架构
Exchange 交换器机制
urql 的架构核心是 Exchange——一种函数式管道中间件。每个 Exchange 是一个高阶函数,接收一个 ExchangeInput 并返回一个函数,该函数接收一个操作流(Source<Operation>),返回一个结果流(Source<OperationResult>)。
Client → [DedupExchange] → [CacheExchange] → [FetchExchange] → GraphQL Server
↑ |
└────────────── 结果流(Observable/Source) ───────────────┘
默认的三个 Exchange:
| Exchange | 职责 |
|---|---|
dedupExchange | 去重——防止相同操作被重复发送 |
cacheExchange | 文档缓存——基于请求结果的简单缓存 |
fetchExchange | 网络请求——实际发送 HTTP 请求到 GraphQL 端点 |
自定义 Exchange 示例:
import { Exchange, Operation, OperationResult } from '@urql/core'
import { pipe, tap, map } from 'wonka'
const loggerExchange: Exchange = ({ forward }) => {
return (ops$) => {
return pipe(
ops$,
tap((op) => console.log('[urql] 操作:', op.kind, op.key)),
forward,
tap((result) => console.log('[urql] 结果:', result.data))
)
}
}
const client = createClient({
url: 'https://api.example.com/graphql',
exchanges: [loggerExchange, dedupExchange, cacheExchange, fetchExchange],
})Client 设计
urql 的 Client 是所有操作的入口点,它负责:
- 管理 Exchange 链——按顺序执行所有 Exchange
- 创建操作(Operations)——将查询、变更、订阅转化为统一的操作对象
- 调度结果——将结果推送给订阅者(React hooks、Vue composables 等)
Client 支持四种请求策略(requestPolicy):
| 策略 | 行为 |
|---|---|
cache-first | 优先缓存(默认) |
cache-only | 仅缓存,无缓存则报错 |
network-only | 仅网络,跳过缓存 |
cache-and-network | 先返回缓存,再请求网络更新 |
缓存策略
urql 提供两级缓存:
- 文档缓存(Document Cache)——内置于
cacheExchange,按查询文档和变量缓存完整响应。适合简单场景,开箱即用。 - 规范化缓存(Normalized Cache)——通过
@urql/exchange-graphcache提供,将数据拆分为独立实体并按 ID 索引,支持跨查询自动更新。适合复杂数据关系场景。
核心特性
1. 渐进式复杂度
urql 的设计哲学是"按需引入复杂度"。最简单的配置只需要一个 URL 和一个 useQuery hook,没有任何样板代码。当需求增长时,可以逐步添加自定义 Exchange、规范化缓存等高级功能,而无需重构现有代码。
2. Exchange 函数式管道
Exchange 机制是 urql 最核心的差异化特性。它基于 Wonka(一个类似 RxJS 的轻量流库),提供强大的函数式组合能力。开发者可以用 pipe、map、filter、mergeMap 等组合子自由编排请求处理逻辑,实现日志、鉴权、重试、离线支持等功能。
3. 多框架统一核心
一个 @urql/core 核心包 + 框架专属绑定(urql、@urql/vue、@urql/svelte 等),确保跨框架一致性。团队成员可以在不同项目中使用不同的框架,但共享同一套 GraphQL 逻辑和缓存策略。
4. 轻量级体积
urql 的核心包体积远小于 Apollo Client。@urql/core 的 minified+gzip 体积约 10-12 KB,而 Apollo Client 约 35-40 KB。在 bundle size 敏感的场景(如移动端、SSR)中优势明显。
5. 规范化缓存(Graphcache)
@urql/exchange-graphcache 是 urql 的官方规范化缓存方案。它将 GraphQL 响应拆分为独立实体,按 __typename + id 索引,支持:
- 自动跨查询更新
- 乐观更新(Optimistic Updates)
- 缓存失效策略配置
- Schema 感知的缓存失效
6. 服务端渲染(SSR)支持
urql 原生支持 SSR,提供 @urql/next 包用于 Next.js 集成。支持 prefetch、rehydrate 等 SSR 模式,确保服务端渲染的数据能无缝传递到客户端。
7. TypeScript 优先
urql 从底层使用 TypeScript 构建,提供完整的类型推导。查询结果类型可以通过 graphql-codegen 自动生成,与查询文档保持同步。
8. 订阅支持
原生支持 GraphQL Subscriptions,可通过 @urql/exchange-graphcache 配合使用,也可使用 @urql/exchange-subscriptions 管理订阅连接。
9. 开发者工具
提供 urql DevTools 浏览器扩展,支持:
- 查看所有 GraphQL 操作和响应
- 检查缓存状态
- 调试 Exchange 管道
- 查看操作时间线
10. 请求策略灵活性
四种内置请求策略(cache-first、cache-only、network-only、cache-and-network)覆盖了绝大多数缓存场景,且可以按查询粒度配置。
生态图
┌─────────────────────────────────────────────────────────────┐
│ urql 生态系统 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 核心层 │
│ ├── @urql/core — 框架无关的核心引擎 │
│ │ │
│ 框架绑定层 │
│ ├── urql — React / Preact 绑定 │
│ ├── @urql/vue — Vue 3 绑定 │
│ ├── @urql/svelte — Svelte 绑定 │
│ ├── @urql/solid — Solid.js 绑定 │
│ ├── @urql/preact — Preact 专用绑定 │
│ │ │
│ 缓存层 │
│ ├── @urql/exchange-graphcache — 规范化缓存(核心扩展) │
│ │ │
│ 平台集成层 │
│ ├── @urql/next — Next.js 集成(SSR/RSC) │
│ │ │
│ Exchange 扩展 │
│ ├── @urql/exchange-retry — 自动重试 │
│ ├── @urql/exchange-request-policy — 请求策略控制 │
│ ├── @urql/exchange-execute — 本地 Schema 执行 │
│ ├── @urql/exchange-context — 动态上下文注入 │
│ ├── @urql/exchange-persisted — 持久化查询(APQ) │
│ │ │
│ 开发工具 │
│ ├── urql-devtools — 浏览器开发者工具扩展 │
│ │ │
│ 代码生成 │
│ ├── graphql-codegen — 配合使用自动生成类型 │
│ │ │
│ 社区扩展(第三方) │
│ ├── urql-exchange-auth — 鉴权 Exchange │
│ ├── urql-multipart — 文件上传支持 │
│ ├── @nanostores/urql — Nanostores 状态管理集成 │
│ │
└─────────────────────────────────────────────────────────────┘
适用场景
1. Bundle Size 敏感的应用
当应用体积是关键指标(如移动端 Web、PWA、嵌入式 Web 视图),urql 的轻量体积(核心约 10KB gzip)相比 Apollo Client(约 35KB gzip)有显著优势。
2. 需要深度定制请求流程的场景
Exchange 机制允许开发者在请求管道的任何环节注入自定义逻辑,适合需要复杂鉴权、动态重试、离线队列、请求转换等高级场景。
3. 多框架团队 / Monorepo
统一核心 + 多框架绑定的设计,使得 urql 成为多框架团队的理想选择。一个核心包服务 React、Vue、Svelte 等多个子应用,减少依赖碎片化。
4. 中小型 GraphQL 应用
对于不需要 Apollo Client 全部功能的中小型应用,urql 提供了"恰到好处"的功能集——足够强大,但不臃肿。
5. Next.js / SSR 项目
@urql/next 提供了开箱即用的 Next.js 集成,支持 App Router、Server Components、prefetch 等现代 SSR 模式。
6. 需要逐步引入复杂度的项目
从简单的文档缓存开始,按需引入规范化缓存、自定义 Exchange 等高级功能。适合那些不确定最终需求复杂度的探索性项目。
7. 教育和学习 GraphQL
urql 的 API 设计简洁直观,核心概念少,非常适合作为学习 GraphQL 客户端的入门工具。
开发与工程化
TypeScript 集成
urql 提供完整的 TypeScript 支持,推荐配合 graphql-codegen 使用:
# 安装代码生成工具
npm install -D @graphql-codegen/cli @graphql-codegen/typed-document-node# codegen.yml
generates:
src/generated/graphql.ts:
plugins:
- typed-document-node
documents: 'src/**/*.graphql'
schema: 'https://api.example.com/graphql'// 使用生成的类型安全查询
import { GetTodosDocument } from './generated/graphql'
import { useQuery } from 'urql'
const [result] = useQuery({ query: GetTodosDocument })
// result.data 类型自动推导测试策略
urql 提供了 createClient 的 mock 支持,便于单元测试:
import { createClient, gql } from '@urql/core'
import { pipe, subscribe } from 'wonka'
const mockClient = createClient({
url: 'test',
fetch: async () => ({
status: 200,
json: async () => ({
data: { todos: [{ id: '1', title: '测试任务' }] },
}),
} as Response),
})
// 测试查询
const result = await pipe(
mockClient.query(gql`query { todos { id title } }`),
subscribe(() => {})
)CI/CD 集成
urql 本身无特殊 CI 需求,标准 Node.js 项目配置即可。推荐在 CI 中加入 GraphQL schema 检查:
# .github/workflows/graphql-check.yml
- name: GraphQL Schema Check
run: npx @graphql-inspector/cli validate src/**/*.graphql schema.graphqlMonorepo 配置
在 Turborepo/pnpm workspace 中,推荐将 @urql/core 和框架绑定提升到根 package.json,避免多版本冲突:
// package.json (root)
{
"pnpm": {
"overrides": {
"@urql/core": "^6.0.0"
}
}
}性能与安全
性能优化
| 优化点 | 说明 |
|---|---|
| 请求去重 | dedupExchange 自动合并相同操作,避免重复请求 |
| 文档缓存 | 内置文档级缓存,减少不必要的网络请求 |
| 流式处理 | 基于 Wonka 的流式架构,避免不必要的重渲染 |
| Tree-shaking | 完全支持 tree-shaking,未使用的功能不会进入打包产物 |
| 惰性求值 | Exchange 管道按需执行,不处理不需要的操作 |
| 批量请求 | 可配合 @urql/exchange-batch 合并多个查询请求 |
安全实践
| 安全点 | 说明 |
|---|---|
| 凭证传输 | 支持 fetchOptions 配置 credentials、headers 等 |
| 鉴权 Exchange | 通过自定义 Exchange 注入 token,避免在查询中暴露敏感信息 |
| CSRF 防护 | 通过 credentials: 'include' + CSRF header 实现 |
| 持久化查询 | @urql/exchange-persisted 支持 APQ(Automatic Persisted Queries),减少查询注入风险 |
| 输入验证 | 建议在服务端做 GraphQL 输入验证,urql 负责传输层安全 |
鉴权 Exchange 示例
const authExchange: Exchange = ({ forward }) => {
return (ops$) => {
return pipe(
ops$,
map((op) => {
const token = getAuthToken()
return {
...op,
context: {
...op.context,
fetchOptions: {
...op.context.fetchOptions,
headers: {
...op.context.fetchOptions?.headers,
Authorization: token ? `Bearer ${token}` : '',
},
},
},
}
}),
forward
)
}
}技术对比
urql vs Apollo Client vs Relay
| 维度 | urql | Apollo Client | Relay |
|---|---|---|---|
| 包体积(gzip) | ~12 KB(核心) | ~35-40 KB | ~25-30 KB(Runtime) |
| 学习曲线 | 低 | 中 | 高 |
| 缓存方式 | 文档缓存 + 可选规范化缓存 | 内置规范化缓存 | 内置规范化缓存(强制) |
| 可扩展性 | Exchange 函数式管道 | Apollo Link 链 | Compiler 插件 |
| 框架支持 | React / Vue / Svelte / Solid / Preact | React / Vue / Angular / Vanilla | 仅 React |
| TypeScript | 原生支持,完整推导 | 原生支持 | 原生支持 |
| SSR 支持 | 原生 + @urql/next | 原生 + @apollo/extras | Next.js 集成 |
| DevTools | 有(urql DevTools) | 有(Apollo DevTools,更成熟) | 无独立 DevTools |
| 社区规模 | 中等(~9K stars) | 最大(~60K stars) | 大(~28K stars) |
| 维护者 | urql-graphql 团队 | Apollo 团队 | Meta(Facebook) |
| GraphQL 规范 | 完整支持 | 完整支持 | 完整支持(含 @defer/@stream) |
| Schema 驱动 | 可选 | 可选 | 强制(需要 compiler) |
| 规范化缓存 | 可选(graphcache) | 内置(核心特性) | 内置(Store) |
| 乐观更新 | 通过 graphcache | 内置 cache.modify | 内置 |
| 订阅 | 原生支持 | 原生支持 | 原生支持 |
| 代码生成 | 配合 graphql-codegen | 配合 graphql-codegen | 专属 Relay Compiler |
| 适合场景 | 轻量应用、多框架、定制需求 | 中大型应用、快速开发 | 超大型应用、数据密集 |
选型建议
- 选 urql:当 bundle size 是硬约束、需要多框架统一、或需要深度定制请求管道时
- 选 Apollo Client:当需要开箱即用的完整方案、丰富的社区生态、或团队对 GraphQL 经验有限时
- 选 Relay:当应用规模极大、数据关系极复杂、且团队有能力投入学习成本时
最佳实践
1. 从文档缓存开始
不要一开始就引入 graphcache。urql 内置的文档缓存已经能覆盖大多数场景。只有当你发现跨查询数据同步成为问题时,才考虑升级到规范化缓存。
// 推荐:先使用默认配置
const client = createClient({
url: '/api/graphql',
})
// 需要时再添加 graphcache
import { cacheExchange } from '@urql/exchange-graphcache'
const client = createClient({
url: '/api/graphql',
exchanges: [
dedupExchange,
cacheExchange({
keys: {
// 自定义缓存键
},
updates: {
Mutation: {
createTodo: (result, args, cache) => {
cache.invalidate({ __typename: 'Todo', id: args.input.id })
},
},
},
}),
fetchExchange,
],
})2. 使用 TypedDocumentNode
始终使用类型安全的查询文档,避免手写泛型:
// 推荐:使用 TypedDocumentNode
import { TypedDocumentNode } from '@urql/core'
const TodosQuery: TypedDocumentNode<{ todos: Todo[] }, {}> = gql`
query Todos {
todos {
id
title
completed
}
}
`
// 或者使用 graphql-codegen 自动生成3. 合理拆分 Exchange
将不同职责的逻辑拆分为独立的 Exchange,而非写一个巨大的 Exchange:
// 推荐:职责分离
const client = createClient({
url: '/api/graphql',
exchanges: [
dedupExchange,
authExchange, // 鉴权
loggerExchange, // 日志
retryExchange, // 重试
cacheExchange, // 缓存
fetchExchange, // 网络
],
})4. 利用请求策略
根据场景选择合适的请求策略,而非总是使用默认值:
// 用户列表:cache-and-network(先展示缓存,再更新)
const [result] = useQuery({
query: UsersQuery,
requestPolicy: 'cache-and-network',
})
// 表单提交后的详情查询:network-only(确保最新数据)
const [result] = useQuery({
query: UserDetailsQuery,
variables: { id },
requestPolicy: 'network-only',
})5. SSR 时注意数据序列化
在 Next.js 中使用 urql 时,确保正确处理服务端到客户端的数据传递:
// app/layout.tsx
import { Provider, createClient, fetchExchange, cacheExchange } from 'urql'
import { registerExchange } from '@urql/next'
const client = createClient({
url: 'https://api.example.com/graphql',
exchanges: [cacheExchange, fetchExchange],
})
export default function RootLayout({ children }) {
return (
<Provider value={client}>
{children}
</Provider>
)
}6. 避免不必要的重渲染
使用 useMemo 缓存查询变量,避免每次渲染都创建新对象:
function TodoList({ status }: { status: string }) {
const variables = useMemo(() => ({ status }), [status])
const [result] = useQuery({
query: TodosQuery,
variables,
})
// ...
}7. 错误边界处理
为 GraphQL 错误设置全局处理逻辑:
const errorExchange: Exchange = ({ forward }) => {
return (ops$) => {
return pipe(
ops$,
forward,
tap(({ error, operation }) => {
if (error) {
// 全局错误处理:上报、Toast 等
console.error(`[GraphQL Error] ${operation.kind}:`, error)
errorReporter.capture(error)
}
})
)
}
}技术局限与边界
已知局限
-
社区规模较小:相比 Apollo Client(~60K stars),urql 的社区规模较小(~9K stars),第三方生态、教程和问答资源相对有限。遇到复杂问题时,可能需要直接阅读源码。
-
规范化缓存功能较弱:
@urql/exchange-graphcache功能完备性不如 Apollo Client 的内置缓存。例如,cache.modify等高级缓存操作 API 不如 Apollo 丰富,跨查询的复杂依赖关系处理需要更多手动配置。 -
DevTools 成熟度:urql DevTools 功能相对基础,不如 Apollo DevTools 完善。在复杂缓存调试、性能分析等方面可能不够用。
-
缺乏内建分页/无限滚动抽象:Apollo Client 提供了
fetchMore、updateQuery等内建分页支持,urql 需要手动实现或通过 Exchange 扩展。 -
React Server Components 集成仍在演进:
@urql/next对 Next.js App Router 和 RSC 的支持仍在发展中,部分边缘场景可能需要自行处理。 -
单向数据流约束:urql 的 Exchange 管道是单向的,某些需要双向通信的场景(如复杂的订阅重连逻辑)实现起来较为复杂。
-
文档和示例覆盖不足:部分高级用法(如复杂 Exchange 编写、graphcache 高级配置)的文档和示例不够详尽。
迁移注意事项
从 Apollo Client 迁移到 urql 时需要注意:
- Apollo 的
cache.modify、cache.readQuery、cache.writeQuery等 API 在 urql 中没有直接对等物,需要通过 graphcache 的updates配置实现类似效果 - Apollo 的
InMemoryCache配置项(如typePolicies、fieldPolicies)需要转换为 graphcache 的keys、updates、resolvers配置 - Apollo 的
RefetchQueries模式在 urql 中通过cache.invalidate+requestPolicy: 'network-only'实现
学习资源
官方资源
- urql 官方文档 — 核心概念和 API 参考
- urql GitHub 仓库 — 源码、Issues 和 Discussions
- Exchange 编写指南 — 官方 Exchange 开发教程
- 架构文档 — 深入理解 urql 内部设计
文章与教程
- Why I (finally) switched to urql from Apollo Client — LogRocket 博客,详细对比和迁移经验
- GraphQL and URql by Example — 通过实例学习 urql
- Understand Urql's Exchanges and Request Policies — 深入理解 Exchange 和请求策略
- Exploring GraphQL Clients: Apollo vs Relay vs URQL — Hasura 的三大客户端对比
- urql vs Apollo Client:2025年前端GraphQL终极对决指南 — 中文 2025 年对比指南
视频
- But Can Your GraphQL Client Do This? — A Deep-Dive Into urql — 深入 urql 设计决策和高级特性
- Can URQL replace Apollo Client? URQL tutorial with SSR and SSG — Next.js 中替换 Apollo 的实操教程
社区
- GitHub Discussions — 提问和讨论
- urql-graphql GitHub Org — 所有相关仓库
2026 年现状
版本演进
截至 2026 年 7 月,urql 生态系统已经历了多次重大版本迭代:
| 时间 | 事件 |
|---|---|
| 2019 年 | Formidable Labs 发布 urql v1 |
| 2021 年 | v3 发布,转向 ES2015+ |
| 2023 年 3 月 | v4 发布,移除 IE11 支持,严格化 TypeScript 泛型 |
| 2025 年 9 月 | urql v5.0.0 发布,核心包升级到 v6 |
| 2026 年 7 月 | urql v5.0.3 / @urql/core v6.0.3(最新) |
当前定位
urql 在 2026 年的 GraphQL 客户端生态中定位为:
- 轻量替代方案:当 Apollo Client 过于臃肿时的首选替代
- 多框架统一方案:唯一真正提供 React/Vue/Svelte/Solid/Preact 统一核心的成熟 GraphQL 客户端
- 可定制性标杆:Exchange 架构提供了 GraphQL 客户端中最强的可定制能力
发展趋势
- 持续活跃开发:GitHub 上持续有提交和 Issue 处理,核心团队保持活跃
- Next.js 深度集成:
@urql/next持续跟进 Next.js 最新版本(App Router、Turbopack 等) - 类型安全增强:配合
graphql-codegen的类型推导体验持续改善 - 性能持续优化:如最近的
perf: don't serialize data to IDB等性能优化持续进行中 - 社区稳定增长:虽然增长速度不如 Apollo,但社区质量和贡献者活跃度保持稳定
是否值得采用?
推荐采用的场景:
- 新项目且团队偏好轻量方案
- 多框架 Monorepo
- Bundle size 有严格要求
- 需要深度定制请求管道
需要谨慎的场景:
- 团队 GraphQL 经验有限,需要开箱即用的完整方案(Apollo 更合适)
- 超大规模应用,需要最成熟的缓存和 DevTools 支持
- 强依赖
cache.modify等高级缓存操作
总结:urql 是 GraphQL 客户端生态中"少即是多"理念的最佳实践。它用 Exchange 管道这一优雅架构,在保持极小体积的同时提供了强大的可扩展性。对于追求轻量、灵活和多框架一致性的团队,urql 是 Apollo Client 之外最值得考虑的选择。