使用 cm6-graphql 为 CodeMirror 6 集成 GraphQL 语言支持解析、自动补全与 Schema 驱动的 Lint【免费下载链接】graphiqlGraphiQL the GraphQL LSP Reference Ecosystem for building browser IDE tools.项目地址: https://gitcode.com/GitHub_Trending/gr/graphiqlcm6-graphql 是 GraphQL 官方 GraphiQL 仓库中发布的 CodeMirror 6 语言扩展包它把 GraphQL 词法/语法解析、基于 GraphQL Schema 的自动补全、校验与文档跳转封装为一组标准 CodeMirror 6 扩展Extension。本文以 packages/cm6-graphql/README.md 为主线结合包内源码与仓库示例完整讲解从安装接入、Schema 热更新到补全 / Lint / 文档跳转等高级能力的配置方法帮助你在自己的浏览器编辑器项目中快速落地一个 Schema 驱动的 GraphQL 编辑器。一、包定位与设计理念CodeMirror 6 的定制完全通过扩展Extension机制完成编辑器自身只提供内核所有语法、补全、校验能力都由扩展注入。cm6-graphql 正是这样一组扩展它在 graphql.ts 中把四个子能力合并成一个开箱即用的graphql()扩展数组graphqlLanguageSupport()注入基于 Lezer 语法生成器产出的 GraphQL 解析器language.tscompletionSchema 驱动的自动补全completions.tslint基于graphql-language-service的语法与 Schema 校验lint.tsjump按住修饰键点击 token 跳转到文档jump.ts。同时通过stateExtensions把当前 GraphQL Schema 与扩展选项存入 CodeMirror 的 StateField 中state.ts使得补全、Lint 等能力可以在 Schema 更新后立即响应。包本身保持极轻依赖运行时只依赖graphql-language-service见 package.jsongraphql与全部codemirror/*包都放在 peerDependencies 中由宿主项目统一提供版本避免多实例冲突。二、安装与最小接入2.1 安装依赖npm install cm6-graphql同时确保宿主项目已安装 peer 依赖CodeMirror 6 系列与graphqlnpm install codemirror codemirror/state codemirror/view codemirror/autocomplete codemirror/language codemirror/lint graphqlpeerDependencies 对graphql的版本要求为^15.5.0 || ^16.0.0 || ^17.0.0见 package.json主流 GraphQL 版本均可使用。2.2 创建编辑器实例import { basicSetup, EditorView } from codemirror; import { graphql } from cm6-graphql; const view new EditorView({ doc: mutation mutationName { setString(value: newString) }, extensions: [basicSetup, graphql(myGraphQLSchema)], parent: document.body, });要点说明graphql(schema, opts)的第一个参数是GraphQLSchema实例来自graphql包可省略省略后自动补全与 Lint 不会生效第二个参数是GqlExtensionsOptions选项对象详见下文第三节extensions数组中basicSetup保证基本编辑体验graphql()负责 GraphQL 语言能力。注意cm6-graphql 只负责语言能力不包含主题。CodeMirror 6 的样式配色、光标、选中态需要你自己引入主题可以参考仓库中的完整示例 examples/cm6-graphql-parcel/src/index.ts其中组合了lineNumbers()、bracketMatching()、closeBrackets()、history()、autocompletion()以及oneDark暗色主题也可以参阅 CodeMirror 6 官方样式文档自行组合。三、GqlExtensionsOptions 选项全解在 interfaces.ts 中定义了完整的扩展选项每个选项都可以按需配置选项类型说明showErrorOnInvalidSchemaboolean当传入的 Schema 无法通过validateSchema校验时是否在文档顶部显示整段错误。默认值为true见 state.tsonShowInDocs(field?, type?, parentType?) void在文档中查看字段时触发回调接收field字段名、type类型、parentType父类型三个参数通常用于打开文档面板onFillAllFields(view, schema, query, cursor, token) void触发填充全部字段命令时回调可借此实现 GraphiQL 的自动填充全部必填字段功能onCompletionInfoRender(gqlCompletionItem, ctx, item) Node \| PromiseNode \| null \| null自定义补全项信息浮层的渲染函数返回一个 DOM 节点autocompleteOptionsAutocompleteSuggestionOptions透传给graphql-language-service的自动补全选项如是否需要统计补全命中数等见 completions.ts四、动态更新 Schema当编辑器运行期间需要切换 Schema例如用户切换了 GraphQL 端点时调用updateSchema传入EditorView实例与新 Schema 即可import { updateSchema } from cm6-graphql; const onNewSchema schema { updateSchema(view, schema); };其底层实现并不重建编辑器而是向编辑器派发一个状态效果StateEffect来更新存储 Schema 的 StateField见 state.ts补全与 Lint 会通过needsRefresh感知 Schema 变化并立即用新 Schema 重新计算诊断结果见 lint.ts因此无需重新创建 EditorView 即可热切换 Schema。如果你还需要动态更新选项可对称地使用updateOpts(view, opts)读取当前 Schema 与选项则可使用getSchema(state)与getOpts(state)见 state.ts。五、深入源码四合一能力如何工作5.1 解析与高亮Lezer 语法graphqlLanguageSupport()使用 Lezer 语法生成器编译的 syntax.grammar 构建LRLanguage并通过styleTags把Variable、BooleanValue、Comment、IntValue、FloatValue、EnumValue、DirectiveName等节点映射为 CodeMirror 高亮标签同时注册了缩进与折叠规则花括号包围的节点使用delimitedIndent/foldInside见 language.ts。注释标记为#并在输入{/}时自动缩进。语法正确性由 Lezer 官方的fileTests驱动测试用例存放在 packages/cm6-graphql/tests/cases.txt 与 types.txt由 test.spec.ts 逐个加载断言可视为语法的权威行为清单。5.2 自动补全Schema 驱动补全扩展从状态中取出 Schema用当前光标位置前的单词计算补全上下文然后调用graphql-language-service的getAutocompleteSuggestions生成补全项completions.ts。只有按下触发字符[a-zA-Z0-9_(]或显式触发如 CtrlSpace时才会弹出候选每个补全项自带detail与文档浮层若未配置onCompletionInfoRender默认把documentation或弃用原因渲染进一个div中展示。5.3 Lint双层校验Lint 扩展做两层检查lint.ts先用validateSchema(schema)校验 Schema 自身合法性若非法且showErrorOnInvalidSchema为真则在整篇文档上标记一条 error可用于快速发现加载了错误 SchemaSchema 合法时调用getDiagnostics对当前文档做 GraphQL 语法与规则校验并把graphql-language-service返回的行列位置换算成 CodeMirror 的文档偏移输出error / warning / info三级诊断。5.4 文档跳转修饰键 点击jump是一个domEventHandlers扩展jump.ts当按住修饰键macOS 为Cmd其余平台为Ctrl见 helpers.ts点击当前 token 时通过getTokenAtPositiongetTypeInfo解析出字段名、类型与父类型并调用onShowInDocs回调——这正是示例中在文档中查看Show in Docs能力的基础。六、完整示例参考仓库提供了一套可直接运行的 Parcel 示例 examples/cm6-graphql-parcel其 index.ts 展示了在生产中如何组合完整编辑器const state EditorState.create({ doc: query, extensions: [ bracketMatching(), closeBrackets(), history(), autocompletion(), lineNumbers(), oneDark, syntaxHighlighting(oneDarkHighlightStyle), graphql(TestSchema, { onShowInDocs(field, type, parentType) { alert(Showing in docs.: Field: ${field}, Type: ${type}, ParentType: ${parentType}); }, onFillAllFields(view, schema, _query, cursor, token) { alert(Filling all fields. Token: ${token}); }, }), ], });TestSchema定义在同目录的 testSchema.ts 中查询样例见 sample-query.ts。仓库还保留了使用旧版 CodeMirror 6 legacy 语法的 cm6-graphql-legacy-parcel 示例可作为对照。七、常见问题与边界说明Schema 未传时不工作graphql()不传 Schema 时补全与 Lint 会直接返回空结果completions.ts、lint.ts但语法高亮、缩进、折叠仍可用如何同时接入多个编辑器每个EditorView各自持有独立的 Schema StateField互不干扰只需为每个实例调用一次graphql(schema)版本配套以当前仓库 package.json 为准cm6-graphql 版本为 0.2.2peer 依赖覆盖 CodeMirror 6 系列与graphql15/16/17接入时请保持宿主版本在兼容范围内样式需自理包不内置主题请按第三节所述方式引入 CodeMirror 主题。至此你已经掌握了从最小接入、Schema 热更新到补全 / Lint / 文档跳转的完整配置路径可以在自己的项目中快速构建一个 Schema 驱动的 GraphQL 编辑体验。【免费下载链接】graphiqlGraphiQL the GraphQL LSP Reference Ecosystem for building browser IDE tools.项目地址: https://gitcode.com/GitHub_Trending/gr/graphiql创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
