You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Webpack拆分大型GraphQL常量文件至对应业务Chunk

问题背景

我用graphql-code-generator生成了一个包含大量常量与类型的文件graphql.ts,分析Webpack打包Chunk后发现:

  • graphql.ts - 600KB
  • Chunk1.ts - 40KB
  • Chunk2.ts - 80KB
  • Chunk3.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或工具生态是否有变化
  • 相关讨论区有类似问题,但未得到有效回复
替代思路:强制代码复用+摇树优化

理论上可以按以下逻辑实现:

  1. 强制将graphql.ts的内容复制到每个业务Chunk中
  2. 依赖摇树优化剔除每个Chunk中未使用的部分
  3. 最终每个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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 10:12:34