
基于 monaco-graphql 与 Vite 构建 React GraphQL 编辑器的完整实战指南【免费下载链接】graphiqlGraphiQL the GraphQL LSP Reference Ecosystem for building browser IDE tools.项目地址: https://gitcode.com/GitHub_Trending/gr/graphiql导读本指南以仓库内examples/monaco-graphql-react-vite示例为核心讲解如何用 React Vite 组合最简落地monaco-graphql实现支持 GraphQL 语法高亮、补全、校验、变量 JSON 联动校验与一键执行查询的完整编辑器。读完本文你将掌握 monaco-graphql 的 worker 配置、schema 加载、模型Model管理、自定义命令绑定等关键技术可直接照搬到自己的浏览器 IDE 或内部工具中。示例项目概览该示例位于 examples/monaco-graphql-react-vite按原文档的描述它是一个extremely naive minimalist极度朴素且最小化的monaco-graphql与react的结合实现以vite作为打包器。虽然代码刻意保持精简但它完整串联了 monaco-graphql 的核心能力四个并排的 Monaco 编辑器GraphQL 操作operations、变量variables、响应response和 TypeScript 模板ts通过 introspection内省查询从远端 GraphQL 服务动态加载 schemaGraphQL 与 JSON 变量之间的跨语言联动校验Ctrl/Cmd Enter自定义命令一键执行查询查询内容自动持久化到localStorage。该工作区在仓库中还有一个特殊定位原文档指出它可以用于为graphiql/react原型化组件与 hooksThis workspace could be used to help us prototype components hooks forgraphiql/react因此阅读本示例代码也是理解 GraphiQL 生态内部编辑器实现思路的捷径。环境准备与启动原文档给出了两步启动流程结合仓库根目录与示例的 package.json 可以明确其前置条件在 monorepo 根目录安装依赖并构建yarn yarn build该示例通过vite.config.ts中的自定义插件watchPackages直接监听monaco-graphql与graphql-language-service两个本地包的源码见下文“Vite 配置细节”因此必须先在根目录构建这些包示例才能引用到最新的本地产物。进入示例目录启动开发服务器cd examples/monaco-graphql-react-vite yarn dev示例自身的脚本见 package.json包含脚本命令作用devvite启动开发服务器默认 5173 端口buildvite build生产构建startvite preview预览生产构建产物其运行时依赖包括monaco-graphql、monaco-editor、graphql、graphiql/toolkit、jsonc-parser以及react/react-dom^19开发依赖为vite^6与vitejs/plugin-react。TypeScript 配置见 tsconfig.json采用strict模式与react-jsx运行时。核心架构四个 Model 与四个 Editor示例的主组件是 src/editor.tsx 中的Editor布局由 src/globals.css 支撑渲染为两个pane每个 pane 内两个编辑器上排是 operations 与 variables下排是 response 与 ts。每个编辑器都对应一个独立的Uri与初始内容定义在 src/constants.ts用途Uri初始内容查询操作Uri.file(operations.graphql)默认示例查询含一处刻意拼错的字段emoj用于演示 schema 加载后的校验变量Uri.file(variables.json){ code: UA }响应Uri.file(response.json)空字符串TS 模板Uri.file(typescript.ts)makeOpTemplate(operations)生成的 TS 代码getOrCreateModel是一个关键工具函数constants.ts它以uri为键若已存在对应 Model 则复用否则editor.createModel(value, language, uri)新建。语言后缀由uri.path推断且ts会被映射为typescript——这是 Monaco 的语言 id 规则。在Editor的useEffect中四个editor.create共享同一份DEFAULT_EDITOR_OPTIONS见 constants.ts主题为vs-dark、关闭 minimap并对 response 额外设置readOnly: true对 ts 编辑器开启smoothScrolling与semanticHighlighting.enabled: true并显式指定language: typescript。effect 的清理函数会把所有 editor、model 与监听 disposable 统一dispose()避免内存泄漏。Vite 下 Monaco Worker 的配置要点Monaco 的许多语言能力运行在 Web Worker 中而 Vite 对 Worker 的加载有特殊要求。示例在入口 src/index.tsx 中给出了标准做法通过?worker后缀导入四个 Worker 并在globalThis.MonacoEnvironment.getWorker中按label分发import JsonWorker from monaco-editor/esm/vs/language/json/json.worker.js?worker; import EditorWorker from monaco-editor/esm/vs/editor/editor.worker.js?worker; import TSWorker from monaco-editor/esm/vs/language/typescript/ts.worker.js?worker; import GraphQLWorker from monaco-graphql/esm/graphql.worker.js?worker; globalThis.MonacoEnvironment { getWorker(_workerId: string, label: string) { switch (label) { case json: return new JsonWorker(); case graphql: return new GraphQLWorker(); case typescript: return new TSWorker(); } return new EditorWorker(); }, };代码中的注释说明了原因Vite 不支持直接通过new Worker(new URL(...))从裸模块路径实例化 Worker它必须预先静态地感知你在加载一个 Web Worker?worker导入正是让 Vite 能够处理该模块的标准方式。此外为了让 TypeScript 模式正常工作editor.tsx 顶部还导入了 Monaco 的 TypeScript 基础语言、peekView、parameterHints等 contribution 模块。对应地vite.config.ts 对 Worker 产物做了专门配置worker: { format: es, rollupOptions: { output: { entryFileNames: workers/[name].js, chunkFileNames: workers/[name].js, }, }, },并关闭生产构建压缩minify: false保持 chunk 命名可读。本地包热更新插件 watchPackagesvite.config.ts 中定义了一个名为vite-plugin-watch-packages的插件在buildStart时对monaco-graphql与graphql-language-service调用this.addWatchFile(require.resolve(packageName))使 Vite 监听这两个本地包的入口源码变动即可触发重载——这是 monorepo 中“边改 LSP 包边看示例效果”的开发利器。Schema 加载introspection createGraphiQLFetcher示例演示了从远端服务动态获取 schema 的标准链路核心在 editor.tsx 的getSchema与graphiql/toolkit的 fetcherconst fetcher createGraphiQLFetcher({ url: GRAPHQL_URL }); async function getSchema(): PromiseIntrospectionQuery { const data await fetcher({ query: getIntrospectionQuery(), operationName: IntrospectionQuery, }); const introspectionJSON data in data (data.data as unknown as IntrospectionQuery); if (!introspectionJSON) { throw new Error(this demo does not support subscriptions or http multipart yet); } return introspectionJSON; }默认 GraphQL 端点是https://countries.trevorblades.com见 constants.ts使用graphql包导出的getIntrospectionQuery()生成标准内省查询createGraphiQLFetcher来自graphiql/toolkit实现位于 packages/graphiql-toolkit/src/create-fetcher自动处理请求序列化与响应包装。schema 加载完成后通过 monaco-graphql 的 API 注入MONACO_GRAPHQL_API.setSchemaConfig([ { introspectionJSON, uri: my-schema.graphql }, ]);setSchemaConfig是MonacoGraphQLAPI的公开方法见 [packages/monaco-graphql/src/api.ts#L127-L150]用于整体覆盖当前 schema 配置schema 一旦就绪worker 中的语言服务便会被实例化随之激活补全、校验、跳转等能力。示例在 editor.tsx 中用独立的useEffect管理加载状态loading/schemastate避免重复触发。值得注意的是getSchema通过fetcher返回的 Promise 直接解构data.data而执行查询时则将其视为异步迭代器result.next()注释明确指出当前 demo 仅支持单次 HTTP GET/POST不支持 multipart 上传与 subscriptions——这是移植时需要注意的能力边界。initializeMode 与变量 JSON 联动校验monaco-graphql 的initializeMode是同步初始化 API 的入口实现见 [packages/monaco-graphql/src/initialize.ts#L20-L33]首次调用时创建MonacoGraphQLAPI实例随后异步加载graphqlMode完成模式装配之后可随时通过返回的 API 惰性更新 schema 与诊断配置。示例在 constants.ts 中做了非常有代表性的配置——让 variables 编辑器跟随 operations 的内容实时生成 JSON Schema 校验export const MONACO_GRAPHQL_API initializeMode({ diagnosticSettings: { validateVariablesJSON: { [OPERATIONS_URI.toString()]: [VARIABLES_URI.toString()], }, jsonDiagnosticSettings: { validate: true, schemaValidation: error, allowComments: true, trailingCommas: ignore, }, }, });validateVariablesJSON声明键为 operations Model 的 uri、值为 variables Model 的 uri 列表。当你在 operations 中声明query Example($code: ID!, $filter: LanguageFilterInput!)时variables 编辑器会自动获得由graphql-language-service的getVariablesJSONSchema见 packages/graphql-language-service/src/utils/getVariablesJSONSchema.ts推导出的 JSON Schema并实时校验jsonDiagnosticSettings开启 JSON 校验并把 schema 校验级别设为error同时允许注释与尾随逗号示例默认变量内容为 JSONC 风格jsonc-parser与languages.json.jsonDefaults.setDiagnosticsOptions的双重设置是为了“初始变量带注释时不闪报错”见 constants.ts 的注释。这种“GraphQL 操作 → 变量 JSON Schema → JSON 编辑器校验”的级联正是 monaco-graphql 区别于普通 GraphQL 高亮的杀手级能力也是本示例最值得复用的片段。一键执行自定义命令与防抖持久化示例通过editor.addAction为 operations 与 variables 两个编辑器注册了自定义命令graphql-runeditor.tsxconst queryAction: editor.IActionDescriptor { id: graphql-run, label: Run Operation, contextMenuOrder: 0, contextMenuGroupId: graphql, keybindings: [KeyMod.CtrlCmd | KeyCode.Enter], async run() { const result await fetcher({ query: MODEL.operations.getValue(), variables: JSONC.parse(MODEL.variables.getValue()), }); const data await result.next(); MODEL.response.setValue(JSON.stringify(data.value, null, 2)); }, };绑定Ctrl/Cmd EnterKeyMod.CtrlCmd | KeyCode.Enter同时作用于 macOS 的 Cmd 与其他平台的 Ctrl命令同样出现在右键菜单contextMenuGroupId: graphql与 F1 命令面板中执行时用jsonc-parser解析变量容忍注释响应结果美化后写入 response Model。同时示例对 operations 与 variables 的onDidChangeContent做了300ms 防抖写入localStorageeditor.tsx且 initialValue 也优先从localStorage恢复见 constants.ts实现了编辑内容的刷新不丢失。其中debounce是一个约 20 行的自实现工具函数editor.tsx也可替换为graphiql/react的useDebounce等现成实现——这也呼应了原文档“用于原型化 graphiql/react 组件与 hooks”的定位。GraphQL 到 TypeScript 模板的实时同步示例的第四个编辑器ts演示了一个颇具巧思的联动operations 内容变化时用makeOpTemplate生成对应的 TypeScript 代码并写入 ts Modeleditor.tsx。makeOpTemplateconstants.ts的语义是用graphql包的parse将操作字符串解析为 AST再用print重新格式化最后包装为“带类型标注的 template literal”const graphql (arg: TemplateStringsArray): string arg[0] const op graphql query Example($code: ID!, $filter: LanguageFilterInput!) { ... } 若解析失败如用户正在输入、语法不完整则回退为上一次成功格式化的内容prettyOp避免把半成品 AST 打爆 ts 编辑器。配合 ts 编辑器开启的semanticHighlighting.enabled这个面板可以直观地看到 GraphQL 与 TypeScript 两种语言模式在同一页面共存协作。关键文件速查示例入口与 Worker 装配src/index.tsx编辑器主组件与执行逻辑src/editor.tsx常量、URI、初始化与工具函数src/constants.tsVite 配置含 worker 输出与本地包监听vite.config.ts依赖与脚本package.jsonmonaco-graphql 初始化实现packages/monaco-graphql/src/initialize.tsmonaco-graphql API 与 schema 配置packages/monaco-graphql/src/api.ts变量 JSON Schema 推导packages/graphql-language-service/src/utils/getVariablesJSONSchema.ts小结examples/monaco-graphql-react-vite虽然自称“朴素”却是一条信息密度极高的最小可行实现它一次性覆盖了 Vite 的 worker 装配、introspection schema 加载、跨语言诊断联动、自定义命令执行与持久化、双语言模板同步等 monaco-graphql 集成中的全部高频痛点。将其与 packages/monaco-graphql 的 README 及源码对照阅读你就能从“能跑通”进阶到“知其所以然”并轻松迁移到自己的 React Vite 项目中。【免费下载链接】graphiqlGraphiQL the GraphQL LSP Reference Ecosystem for building browser IDE tools.项目地址: https://gitcode.com/GitHub_Trending/gr/graphiql创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考