TypeScript环境下跨文件引用GraphQL Fragments返回undefined问题求助
我来帮你排查下这个问题,从你给出的代码来看,SUBJECT_FRAGMENT导入后变成undefined,大概率是文件路径匹配错误或者模块解析的问题,下面是几个常见的排查方向:
1. 检查导入路径的文件名匹配
你在tracker.ts里写的导入是:
import { SUBJECT_FRAGMENT } from './subjects';
但你的片段文件是subject.ts(单数),如果文件名确实是subject.ts,那路径应该改成./subject:
import { SUBJECT_FRAGMENT } from './subject';
如果你的文件是放在subjects目录下的index.ts或者subject.ts,那路径要对应调整,比如./subjects/subject或者./subjects(如果subjects目录有导出该片段的index.ts)。
2. 确认片段的导出和导入方式正确
确保subject.ts里的SUBJECT_FRAGMENT确实是命名导出,你的代码里已经用了export const SUBJECT_FRAGMENT = gql...``,这部分是对的,但有时候如果TypeScript配置了esModuleInterop或者allowSyntheticDefaultImports,不小心用了默认导入也会出问题,比如:
// 错误示例:如果是命名导出,不能用默认导入 import SUBJECT_FRAGMENT from './subject';
保持你当前的命名导入方式就没问题,只要路径正确。
3. 检查graphql-tag的处理和TypeScript配置
有时候TypeScript的模块解析或者babel/webpack对gql标签的处理可能导致导入异常:
- 确保你的项目里正确配置了
graphql-tag的类型,安装@types/graphql和@types/graphql-tag(如果还没装的话):
npm install @types/graphql @types/graphql-tag --save-dev
- 如果用了webpack,确认
graphql-tag/loader或者babel-plugin-graphql-tag已经正确配置,确保gql标签编译后的DocumentNode能被正确导入。
4. 验证片段是否被正确拼接
另外,你可以在tracker.ts里打印一下SUBJECT_FRAGMENT的值,看看是不是真的undefined:
import { SUBJECT_FRAGMENT } from './subject'; console.log(SUBJECT_FRAGMENT); // 检查控制台输出
如果打印出来是undefined,那肯定是导入路径的问题;如果是DocumentNode对象,那可能是拼接的时候的问题?不过这种情况很少见,因为你拼接TRACKER_FRAGMENT是正常的,所以大概率还是导入的问题。
最后,修正路径后的完整tracker.ts示例:
import { gql } from '@apollo/client'; import { SUBJECT_FRAGMENT } from './subject'; // 修正路径 export const TRACKER_FRAGMENT = gql` fragment TrackerFields on Tracker { id name slug purpose type } `; export const trackerQuery = gql` query TrackerQuery($id: ID!) { tracker(trackerId: $id) { ...TrackerFields subjects { ...SubjectFields } } } ${TRACKER_FRAGMENT} ${SUBJECT_FRAGMENT} `;
内容的提问来源于stack exchange,提问作者Jonathan

