如何通过Webpack拆分大型GraphQL常量文件至对应业务Chunk
问题背景
我用graphql-code-generator生成了一个包含大量常量与类型的文件graphql.ts,分析Webpack打包Chunk后发现:
graphql.ts- 600KBChunk1.ts- 40KBChunk2.ts- 80KBChunk3.ts- 50KB- 其他Chunk...
graphql.ts的内容结构示例如下:
// 类型定义 type MyType = {} type MyType2 = {} enum MyEnum {} // 大量常量 const MyQueryDocument1 = { /* 完全独立的JSON对象 */ }; const MyQueryDocument2 = { /* 完全独立的JSON对象 */ }; const MyQueryDocument3 = { /* 完全独立的JSON对象 */ }; // 业务文件引用情况 // 文件1使用: MyQueryDocument1 // 文件2使用: MyQueryDocument2 // 文件3使用: MyQueryDocument3
其中包含大量类型、枚举定义,以及基本无复用的常量,每个业务Chunk仅用到其中单个常量。
核心需求
如何拆分graphql.ts,让每个业务Chunk仅包含自身用到的常量部分,最终达到如下效果:
graphql.ts- 30KB(仅保留枚举定义,常量移至对应业务Chunk)Chunk1.ts- 70KB(仅包含MyQueryDocument1)Chunk2.ts- 100KB(仅包含MyQueryDocument2)Chunk3.ts- 70KB(仅包含MyQueryDocument3)- 其他Chunk...
无需分步教程,提供可行的方向指南或案例即可。
已尝试方案
我已经试过以下方法,但都没解决问题:
- 咨询ChatGPT,回答与需求不符
- 从Webpack上游拆分
graphql.ts的思路行不通:near-operations-file仅生成类型(虽支持生成钩子和组件,但我不需要)- 已启用graphql-code-generator的代码拆分特性,但仍生成大型
graphql.ts文件 graphql-let可能有用,但不支持片段,无法使用- 我的codegen脱敏配置如下:
import type { CodegenConfig } from "@graphql-codegen/cli"; const config: CodegenConfig = { overwrite: true, schema: "../schema-folder/*.graphql", documents: [ "src/**/*.{tsx,ts}", "!src/gql/**/*", ], generates: { "src/gql/": { preset: "client", plugins: [], presetConfig: { fragmentMasking: { unmaskFunctionName: "myMaskFunction" }, }, config: { useTypeImports: true }, } }, }
- 配置Webpack的SplitChunks插件使用
chunks: all参数 - 看到6年前有相关回答称无法实现该需求,但不确定当前Webpack或工具生态是否有变化
- 相关讨论区有类似问题,但未得到有效回复
替代思路:强制代码复用+摇树优化
理论上可以按以下逻辑实现:
- 强制将
graphql.ts的内容复制到每个业务Chunk中 - 依赖摇树优化剔除每个Chunk中未使用的部分
- 最终每个Chunk仅保留枚举定义和自身用到的常量,避免冗余
但目前不知道如何实现第一步的强制复制逻辑。
繁琐但可行的替代方案:自定义Babel插件+代码后处理
目前能想到的可行方案是构建一套自定义转换流程,将graphql.ts转换为如下目录结构:
/graphql/ - index.ts(导出所有子文件内容) - types.ts - MyQueryDocument1.ts - MyQueryDocument2.ts - MyQueryDocument3.ts
之后修改graphql-code-generator的Babel插件,让业务代码从graphql/MyQueryDocument1这类单个文件导入常量,而非从整个graphql.ts导入。
内容的提问来源于stack exchange,提问作者Albert Liu
相关产品推荐
相关产品推荐

