GraphQL Codegen无法加载自定义Schema加载器问题求助
GraphQL Codegen自定义Schema加载器加载失败问题解决
报错信息
Failed to load schema from pulse-api: Failed to load custom loader: codegen_schema_loader.js Error: Failed to load custom loader: codegen_schema_loader.js
你的配置与加载器代码
codegen.ts 配置文件
import type { CodegenConfig } from '@graphql-codegen/cli'; const config: CodegenConfig = { overwrite: true, schema: [{ 'pulse-api': { loader: './codegen_schema_loader.js', assumeValidSDL: true, } }], documents: 'src/adapters/worktango/queries/*.graphql', generates: { 'src/gql/': { preset: 'client', plugins: ['typescript', 'typescript-operations', 'typescript-react-apollo'], }, './graphql.schema.json': { plugins: ["introspection"] } }, require: ['ts-node/register'], }; export default config;
自定义加载器 codegen_schema_loader.js
import { buildClientSchema, getIntrospectionQuery } from "graphql"; import { graphqlUrl } from "./src/config/settings/worktango.settings"; import fetch from 'cross-fetch' import { tokens } from "./src/adapters"; export default async () => { const introspectionQuery = getIntrospectionQuery() const authToken = await tokens.getAccessToken(); const response = await fetch(graphqlUrl, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Access-Token': authToken }, body: JSON.stringify({ query: introspectionQuery }) }) const data = await response.json() return buildClientSchema(data.data) }
调试发现的问题函数
async function useCustomLoader(loaderPointer, cwd) { let loader; if (typeof loaderPointer === 'string') { loader = await getCustomLoaderByPath(loaderPointer, cwd); } else if (typeof loaderPointer === 'function') { loader = loaderPointer; } if (typeof loader !== 'function') { throw new Error(`Failed to load custom loader: ${loaderPointer}`); } return loader; }
解决方案
从报错和调试结果来看,getCustomLoaderByPath加载自定义加载器后返回了null,导致判断loader不是函数抛出错误。以下是针对性修复步骤:
1. 统一模块类型,改用TS加载器
你的配置使用ts-node/register处理TS文件,但加载器是JS格式,可能导致导出识别异常。将加载器改为TS文件(codegen_schema_loader.ts),并明确函数导出:
import { buildClientSchema, getIntrospectionQuery } from 'graphql'; import { graphqlUrl } from './src/config/settings/worktango.settings'; import fetch from 'cross-fetch'; import { tokens } from './src/adapters'; export default async function loadSchema() { const introspectionQuery = getIntrospectionQuery(); const authToken = await tokens.getAccessToken(); const response = await fetch(graphqlUrl, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Access-Token': authToken }, body: JSON.stringify({ query: introspectionQuery }) }); const data = await response.json(); return buildClientSchema(data.data); }
同时更新codegen.ts中的loader路径:
loader: './codegen_schema_loader.ts'
2. 确保文件路径解析正确
GraphQL Codegen以项目根目录为cwd,若路径解析存在歧义,改用绝对路径:
import path from 'path'; // ... schema: [{ 'pulse-api': { loader: path.resolve(__dirname, './codegen_schema_loader.ts'), assumeValidSDL: true, } }],
3. 排查依赖与模块加载错误
- 确认
cross-fetch已安装:npm install cross-fetch --save-dev - 检查
./src/config/settings/worktango.settings和./src/adapters的导出是否正确,避免加载时出现未捕获错误导致模块加载失败。可在加载器开头添加日志测试是否被正常加载:console.log('Loader initiated'); // ... 其余代码
4. 调整TS-Node配置
在codegen.ts开头添加TS-Node配置,确保兼容JS/TS混合模块:
require('ts-node').register({ allowJs: true, transpileOnly: true });
或在tsconfig.json中设置allowJs: true。
5. 独立测试加载器
创建测试文件test-loader.ts,单独验证加载器功能:
import loadSchema from './codegen_schema_loader.ts'; (async () => { try { const schema = await loadSchema(); console.log('Schema loaded successfully'); } catch (err) { console.error('Loader error:', err); } })();
运行npx ts-node test-loader.ts,直接定位加载器内部的错误。
内容的提问来源于stack exchange,提问作者Michael Hua
相关产品推荐
相关产品推荐

