ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

在 React 项目中嵌入 Ruru:ruru-components 组件库使用指南与源码解析

在 React 项目中嵌入 Ruru:ruru-components 组件库使用指南与源码解析 在 React 项目中嵌入 Rurururu-components 组件库使用指南与源码解析【免费下载链接】crystal Graphiles Crystal Monorepo; home to Grafast, PostGraphile, pg-introspection, pg-sql2 and much more!项目地址: https://gitcode.com/gh_mirrors/cry/crystal导读ruru-components 是 Graphile Crystal Monorepo 中RuruGrafast 风格 GraphiQL 发行版背后的 React 组件库。当你想把一套开箱即用的 GraphQL IDE含查询编辑、变量编辑、订阅支持、Explain 调试面板、文档浏览与历史记录直接嵌进自己现有的 React 应用而不是通过 ruru 独立服务器提供时ruru-components 就是答案。本文将以 grafast/ruru-components/README.md 为主线完整还原其最小接入流程与 Monaco workers 配置方案并结合 源码 深入讲解 RuruProps 配置项、Explain 调试链路、事件流自动刷新与本地存储机制帮助你真正会用 懂原理。ruru-components 是什么根据 grafast/ruru-components/package.json 的描述ruru-components 是 Grafast-flavoured GraphiQL distribution; the underlying React components——即一个 Grafast 风味的 GraphiQL 发行版所依赖的底层 React 组件。它的定位非常明确ruru 本身是一个完整的 GraphQL IDE 应用可独立运行/由服务器托管而 ruru-components 把这些界面能力拆成可复用的 React 组件供希望在既有 React 工程中嵌入 IDE 的开发者使用。README 原文如此概括The React components behind ruru, in case you want to embed Ruru into an existing React project.从 src/index.tsx 可以看到包的公开 API 极其精简仅导出三样东西export type { Fetcher, RuruProps } from ./interfaces.ts; export { Ruru } from ./ruru.tsx;也就是说你真正需要关心的只有一个组件Ruru /和它的属性类型RuruProps以及可选的Fetcher类型。快速开始最小接入安装与运行环境ruru-components 发布在 npm 上包名ruru-components。根据其 package.json运行环境需要满足Node.js 22engines.nodepeerDependenciesgraphql ^16.9.0需要自行安装React 19 运行时react/react-dom/react-compiler-runtime为其内部依赖。在已有 React 工程中安装方式与普通依赖一致yarn add ruru-components graphql # 或 npm install ruru-components graphql最小使用示例README 给出的核心用法如下以下代码为原文档完整示例可直接复制运行import graphiql/style.css; import graphiql/plugin-explorer/style.css; import ruru-components/ruru.css; // Have Webpack include the Monaco workers import graphiql/setup-workers/webpack; // Or: import graphiql/setup-workers/vite; // Or: see Monaco workers below import { Ruru } from ruru-components; React.render(Ruru endpoint/graphql /);这段代码蕴含了四个关键动作下面逐一拆解导入三份样式表GraphiQL 基础样式、Explorer 插件样式、ruru-components 自身的定制样式ruru.css。包在 exports 字段 中专门导出了./ruru.css说明样式是组件的一等公民缺少它会直接导致布局错乱。设置 Monaco workersGraphiQL 的代码编辑器基于 MonacoVS Code 的编辑器内核其语言服务JSON、GraphQL运行在 Web Worker 中必须显式装配。README 给出了 Webpack 与 Vite 两种自动方案详见下文Monaco workers 配置。导入Ruru组件这是唯一的顶层组件入口。渲染组件Ruru endpoint/graphql /声明式地指定 GraphQL 端点。注意endpoint可以传相对路径如/graphql组件内部会自动拼接为完整地址。只传入一个 endpoint 就够了从 ruru-types/src/index.ts 的RuruProps定义看endpoint是唯一必需的语义化属性其余均为可选。组件内部ruru.tsx会为未显式传入的大量配置提供合理默认值例如inputValueDeprecation默认true提示已弃用的输入值schemaDescription默认truedefaultQuery默认使用组件内置的 defaultQuery.tsshowPersistHeadersSettings默认true提供持久化 Headers开关同时会忽略query、variables这两个已废弃的旧属性并在RuruInner中预留了onEditQuery、responseTooltip、forcedTheme等 GraphiQL 扩展点当前以注释形式标注说明这些透传能力正在演进中。Monaco workers 配置Monaco 编辑器会把 JSON 与 GraphQL 的语言解析放到 Worker 线程中执行。如果直接用Ruru /而不同时装配 workers编辑器往往表现为无语法高亮、无智能提示或直接报错。README 提供了两条路线路线一交给打包器自动处理推荐在 Webpack 工程中只需一行副作用导入import graphiql/setup-workers/webpack;在 Vite 工程中则替换为import graphiql/setup-workers/vite;这两种方式会分别利用 Webpack 的?worker模块规则与 Vite 的 worker 打包能力把 Monaco 的editor.worker、json.worker、graphql.worker自动打包并注册到globalThis.MonacoEnvironment。路线二手动注入 MonacoEnvironment如果打包器方案在你的工程中不可用例如自定义构建链、CDN 分发、或 worker 策略受限README 给出了手动方案——在引入 Ruru 之前于 HTML 中加入如下script typemodule块完整代码可原样复制script typemodule /* Set up monaco workers */ import createJSONWorker from https://esm.sh/monaco-editor/esm/vs/language/json/json.worker.js?worker; import createGraphQLWorker from https://esm.sh/monaco-graphql/esm/graphql.worker.js?worker; import createEditorWorker from https://esm.sh/monaco-editor/esm/vs/editor/editor.worker.js?worker; globalThis.MonacoEnvironment { getWorker(_workerId, label) { switch (label) { case json: return createJSONWorker(); case graphql: return createGraphQLWorker(); default: return createEditorWorker(); } }, }; /script其原理是Monaco 在创建编辑器时会调用MonacoEnvironment.getWorker(workerId, label)我们根据label语言标识返回对应的 Worker 构造器——json返回 JSON 语言 workergraphql返回 Monaco GraphQL 的 worker其余语言一律回退到通用编辑器 worker。这段脚本必须先于Ruru 应用代码执行否则 Monaco 找不到 worker 工厂。RuruProps 完整配置项ruru-components 的全部属性定义集中在 ruru-types/src/index.tsruru-components 只是从该 workspace 包原样再导出见 src/interfaces.ts。核心配置如下属性类型说明endpointstringGraphQL HTTP 端点http://或https://也支持/graphql这类相对路径默认/graphqlsubscriptionEndpointstringGraphQL 订阅端点ws://或wss://。不传时若提供了endpoint会自动推导出 ws 地址fetcherFetcher可选覆盖默认 fetcher来自graphiql/toolkit用于自定义请求/认证逻辑debugToolsArrayexplain \| plan开放给用户的调试工具列表explain输出执行的 SQL、plan输出执行的计划eventSourceInitRuruEventSourceInit透传给new EventSource(url, eventSourceInit)的初始化参数。规范只定义withCredentials但实现可扩展例如reconnectInterval: 1000、maxReconnectAttempts: 3editorTheme/defaultThemestring编辑器主题与默认主题maxHistoryLengthnumber历史记录最大条数initialQuery/initialVariables/initialHeadersstring初始查询、变量、HeadersdefaultQuery/defaultHeadersstring默认查询与默认 HeadersonEditQuery/onEditVariables/onEditHeaders函数编辑回调responseTooltip、defaultEditorToolsVisibility、isHeadersEditorEnabled、forcedTheme、confirmCloseTab、className透传其余 GraphiQL 界面属性原样转发给底层GraphiQLInterfaceendpoint 与订阅端点的自动推导在 useFetcher.ts 中可以看到端点的处理逻辑若endpoint以/开头自动补全为window.location.origin endpoint订阅地址通过makeWsUrl推导相对路径补全为ws://或wss://视当前页面协议而定http(s)://前缀则直接替换为ws(s)://其他形式原样使用仅在显式传入subscriptionEndpoint时才覆盖推导结果。自定义 fetcher 与调试请求头若未传fetcher组件会用createGraphiQLFetcher创建默认 fetcher。当 Explain 功能开启时详见下文fetcher 会自动携带两个调试请求头headers[X-PostGraphile-Explain] on; headers[X-GraphQL-Explain] plan,sql;这组请求头同时作为 WebSocket 连接的wsConnectionParams保证订阅场景下 Explain 能力同样可用。源码级架构Ruru 组件内部长什么样Ruru /并非一个黑盒其内部结构src/ruru.tsx清晰地分为三层GraphiQLProvider ← 全局状态fetcher、插件、默认查询 ExplainContext.Provider ← Ruru 自定义Explain 开关、结果与面板状态 HistoryStore ← 历史记录存储 DocExplorerStore ← 文档浏览存储 RuruInner ← GraphiQLInterface 工具栏 页脚 错误弹窗内置插件集Ruru 预置了 5 个 GraphiQL 插件插件来源用途DOC_EXPLORER_PLUGINgraphiql/plugin-doc-explorer文档浏览器DOWNLOAD_PLUGIN本地 plugins/download.tsx下载查询结果/请求HISTORY_PLUGINgraphiql/plugin-history历史记录explorerPlugingraphiql/plugin-explorer可视化 Schema 浏览器关闭了归属水印showAttribution: falseEXPLAIN_PLUGIN本地 plugins/explain.tsxRuru 核心卖点Explain 面板工具栏与 Options 菜单RuruInner在 GraphiQL 工具栏中注册了三个快捷键按钮Prettify QueryShift-Ctrl-P由 usePrettify.tsx 实现——优先动态加载prettier/standalone及其 estree/babel/graphql 插件用prettier.formatWithCursor分别以graphql查询和jsonc变量/Headers解析器格式化三个编辑器并保留光标位置若 Prettier 在 2 秒内加载失败则回退到 GraphiQL 内置的 prettify 动作Merge QueryShift-Ctrl-M合并查询片段Copy queryShift-Ctrl-C复制当前查询。工具栏右侧的Options下拉菜单由本地状态驱动包含五项开关详见下一节。错误弹窗当 EventSource 连接异常等运行时错误发生时ErrorPopup.tsx 会以浮层形式展示错误信息源码注释也坦承该组件需要更完善的设计与无障碍支持属于仍在打磨的部分。Options 菜单与本地存储机制Options 菜单中的每个开关都与localStorage双向绑定存储实现位于 useStorage.ts。所有键均以Ruru:为前缀除graphiql:explorerIsOpen复用了 GraphiQL 既有键菜单项存储键值效果Explain (if supported)Ruru:explaintrue/开启后向 fetcher 注入调试请求头VerboseRuru:verbosetrue/是否在响应中保留extensions.explain不开启则隐藏CondensedRuru:condensedtrue/为界面追加condensedclass压缩垂直空间onError: PROPAGATERuru:onErrorPROPAGATE传统 GraphQL 错误处理错误正常传播onError: NULLRuru:onErrorNULL客户端负责错误处理对应 Grafast 的 null 语义onError: HALTRuru:onErrorHALT遇到首个错误立即停止执行其中onError是 Grafast 执行语义在界面层的暴露wrappedFetcher会把存储中的onError值作为附加参数合并进每个 fetcher 请求见 useFetcher.ts 中{ ...params, onError }从而让用户在不改服务端代码的情况下切换 Grafast 的错误处理策略。RuruStorage接口还提供了toggle(key)便捷方法内部实现针对condensed做了特判默认为开。所有set操作都会递增一个 revision state 触发重渲染保证 UI 与存储即时同步。ExplainRuru 的调试核心Explain 是 Ruru 区别于普通 GraphiQL 发行版的关键能力也是 ruru-components 中最值得深入的部分。启用条件在 useFetcher.ts 中Explain 的启用需要同时满足const explain options.explain (!props.debugTools || props.debugTools.includes(explain));即用户在 Options 菜单中打开了 Explain 开关且未限制debugTools或debugTools中包含了explain。若你希望完全屏蔽调试能力可显式传debugTools{[]}。数据流开启后fetcher 携带X-PostGraphile-Explain: on与X-GraphQL-Explain: plan,sql请求头服务端PostGraphile / Grafast在响应extensions.explain中返回结构化的解释结果形如interface ExplainResults { operations: Array | { type: sql; query: string; explain?: string } // SQL 操作 | { type: plan; plan: GrafastPlanJSON } // 计划操作 ; }wrappedFetcher在每次非 introspection 响应后若extensions.explain格式合法则延迟 100ms 将其写入 state 并渲染到 Explain 面板同时若未开启 Verbose会通过Object.defineProperty把explain属性改为不可枚举hideProperty做到从结果中隐藏、但面板可见若响应携带的是旧版 PostGraphile v4 的顶层explain数组则兼容转换为type: sql的 Legacy explain 条目introspection 查询会被短路直接返回避免干扰用户视图。Explain 面板plugins/explain.tsx 把 Explain 注册为带放大镜图标的 GraphiQL 插件其内容由 components/Explain.tsx 渲染。面板的尺寸与位置偏好通过 useExplain.ts 持久化到Ruru:explainIsOpen、Ruru:explainSize默认 300px、Ruru:explainAtBottom默认在底部等键中。事件流Schema 变更自动刷新ruru-components 还内置了对 GraphQL Live/Schema 变更事件流的支持。机制如下useGraphQLChangeStream.ts useFetcher.ts默认 fetcher 包装了window.fetch每次响应都会检查X-GraphQL-Event-Stream响应头若存在则以该响应头值为地址创建EventSource支持通过eventSourceInit传入withCredentials、reconnectInterval等扩展选项EventSource 收到change事件时自动触发一次 introspectionrefetch使编辑器内的 Schema 文档与智能提示实时跟随服务端变更连接异常如服务端重启导致 WebSocket 意外终止时会以友好错误信息提示用户而不是输出原始的{isTrusted: true}噪音。这套设计让 Ruru 在开发态schema 热更新与生产态实时 schema 演进下都能保持文档与提示的最新状态。其他使用模式与进阶参考README 明确指出其他使用模式请参考主包 ruru。ruru 提供了独立运行、CLI 与服务器托管等更完整的形态相关文档见 grafast/ruru/README.md其服务端集成、CLI 用法与 HTML 分发方案见 grafast/ruru/src/server.ts、grafast/ruru/src/cli.ts。如果你的诉求是最快的现成 IDE优先使用 ruru 独立包如果你的诉求是把 IDE 深度嵌进自己的 React 应用、并自定义 fetcher 与调试工具ruru-components 就是那个正确的切入点。二者共享同一套 RuruProps 语义迁移成本很低。结语ruru-components 以极小的公开 APIRuruRuruProps封装了一个功能完整的 Grafast 风格 GraphQL IDE开箱即用的五个插件、Monaco workers 的三种装配方案、endpoint驱动的自动 fetcher、Explain 调试链路以及基于localStorage的完整偏好持久化。通过本文对照 README 与 src/ruru.tsx、src/hooks、ruru-types/src/index.ts 等源码阅读你既可以按最小示例快速接入也能深入理解其请求头、错误语义与事件流机制进而在自己的产品中定制出符合需求的 GraphQL 工作台。【免费下载链接】crystal Graphiles Crystal Monorepo; home to Grafast, PostGraphile, pg-introspection, pg-sql2 and much more!项目地址: https://gitcode.com/gh_mirrors/cry/crystal创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表