如何在多项目间共享GraphQL Codegen生成的Fragments?
处理跨项目GraphQL片段复用的最佳实践
核心问题根源
组件库编译后的代码已将原始graphql调用替换为生成后的工具函数,导致应用侧Codegen无法从中提取有效的GraphQL片段定义。解决的核心是让应用侧Codegen能直接获取到未被编译修改的原始片段源信息。
方案1:组件库暴露原始片段源文件
在common-lib中把所有GraphQL片段集中放在独立目录(比如src/graphql/fragments/),并在package.json的files字段中添加该目录,确保发布时包含未编译的源文件:
// common-lib/package.json { "files": [ "dist", "src/graphql/fragments" ] }
然后在应用侧的Codegen配置中直接引入这些源文件:
// app-1/codegen.yml documents: - ./src/**/*.tsx - ./node_modules/common-lib/src/graphql/fragments/**/*.tsx
这种方式让Codegen直接解析原始片段定义,完全避开编译后的代码结构问题。
方案2:组件库生成并导出片段元数据
在common-lib的Codegen配置中启用@graphql-codegen/fragment-matcher插件,生成片段的AST和类型匹配信息,再导出给应用侧注册:
- 组件库Codegen配置添加插件:
// common-lib/codegen.yml generates: ./generated/fragments.ts: plugins: - "@graphql-codegen/fragment-matcher" config: emitLegacyCommonJSImports: false
- 组件库入口导出生成的片段数据:
// common-lib/src/index.ts export * from './generated/fragments';
- 应用侧初始化GraphQL客户端时注册片段:
// app-1/src/graphql/client.ts import { fragments } from 'common-lib'; import { ApolloClient, InMemoryCache } from '@apollo/client'; const cache = new InMemoryCache({ possibleTypes: fragments.possibleTypes, }); // 批量注册所有组件库片段 Object.values(fragments).forEach(frag => cache.registerFragment(frag)); const client = new ApolloClient({ cache, uri: '/graphql', });
同时在应用侧Codegen配置中引入组件库的片段类型定义:
// app-1/codegen.yml schema: - ./schema.graphql - ./node_modules/common-lib/generated/fragments.ts
方案3:临时兼容:保留原始graphql调用
如果不想修改组件库发布逻辑,可以在组件库的编译配置中(如Vite/Babel),让包含内联graphql的文件跳过函数替换:
以Vite为例,在common-lib/vite.config.ts中配置:
export default defineConfig({ build: { rollupOptions: { external: ['graphql'], }, }, });
这样编译后的代码会保留原始graphql导入,应用侧Codegen就能解析到片段定义。但此方案会导致运行时需要解析GraphQL字符串,影响性能,仅适合临时过渡。
关于“注册已生成片段到应用Codegen”的问题
可以实现,但需要组件库导出片段的原始AST或SDL字符串,而非编译后的调用。方案2就是通过生成片段匹配器元数据,让应用侧的缓存和Codegen都能识别组件库的片段。
内容的提问来源于stack exchange,提问作者sjahan
相关产品推荐
相关产品推荐

