如何在没有webpack的typescript节点项目中使用.grapql



我有一个节点,使用expressGraphql的express服务器。我试图在.graphql.gql文件中声明graphql的类型定义,因为随着类型变大,读取string变得困难。

这是我所拥有的:

import testQuery from './test.graphql';
import routes from "./routes";
import { buildSchema } from "graphql";
const schema = buildSchema(testQuery);
// Root resolver
const root = {
message: () => "Hello World!",
};
app.use(
"/api/graphql",
expressGraphQL({
schema,
graphiql: true,
})
);

我的graphql文件//test.graphql

type Book {
message: String
}

我收到一个错误,因为Typescript

找不到模块'/test.graphql'.

我见过有人这样做:

const { makeExecutableSchema } = require('graphql-tools');
const schemaFile = path.join(__dirname, 'schema.graphql');
const typeDefs = fs.readFileSync(schemaFile, 'utf8');
const schema = makeExecutableSchema({ typeDefs });

这样做吗?

那么,我需要什么来配置typescript才能导入并构建模式呢

您可以使用https://github.com/ardatan/graphql-import-node在没有webpack的情况下解决这个问题。

使用yarn add graphql-import-nodenpm install --save graphql-import-node安装,然后使用graphql-import-node/register挂钩(如果使用ts节点(:

ts-node -r graphql-import-node/register index.ts

或者在顶部的文件中导入它,如下所示:

import "graphql-import-node";

在我的案例中,我选择了后面的,因为我已经在测试中使用了ts-node/registermocha -r

您可能还需要将"esModuleInterop": true添加到tsconfig.json中的compilerOptions中。

AFAIK,有两种导入模式文件的方法,1(如上所述直接读取文件,或2(将查询封装在导出的变量中。

// bookSchema.ts <- note the file extension is .ts instead of .graphql
export default `
type Book {
message: String
}
`
// anotherSchema.ts <- note the file extension is .ts instead of .graphql
export default `
type User {
name: String
}
`
// main.ts
import bookSchema from 'bookSchema';
import anotherSchema from 'anotherSchema';
const schema = makeExecutableSchema({ typeDefs: [
bookSchema,
anotherSchema,
] });

这个答案解决了@leogoesger提出的问题。这是一种使用.graphql文件创建模式的模块化方法,无需定义多个makeExecutableSchema调用。

文件夹结构应该看起来像这样才能工作:


src
- graphql
- schema.ts
- bar
- barResolver.ts
- schema.graphql
- foo
- fooResolver.ts
- schema.graphql

schema.graphql包含您的所有类型定义。"feature"解析程序文件包含您的解析程序,该解析程序是一个包含查询和突变的对象。

在您的schema.ts文件中,您将创建这样的合并模式:


import { mergeSchemas, makeExecutableSchema } from "graphql-tools";
import { readdirSync, lstatSync, existsSync } from "fs";
import * as path from "path";
import { importSchema } from 'graphql-import'
import { GraphQLSchema } from 'graphql';
const schemas: GraphQLSchema[] = [];
const isDirectory = dirPath =>  existsSync(dirPath) && lstatSync(dirPath).isDirectory();
const getDirectories = source =>
readdirSync(source).map( name => path.join(source, name) ).filter(isDirectory)
const folders = getDirectories( path.resolve(__dirname, './') )
folders.forEach(folder => {
folder = folder.substr( folder.lastIndexOf("\")+1 )
const {resolvers} = require(`./${folder}/${folder}Resolver`);
const typeDefs = importSchema( path.join(__dirname, `./${folder}/schema.graphql`) );
schemas.push(makeExecutableSchema({resolvers, typeDefs}))
});
const mergedSchemas = mergeSchemas({ schemas })
export default mergedSchemas;

其想法是获取与schema.ts位于同一级别的所有相关目录,然后循环遍历每个特性名称并导入相应的解析器和类型定义。接下来,我们使模式可执行,并将其添加到我们的模式数组中。最后,我们使用mergeSchemas将模式缝合在一起,从多个API创建一个GraphQL模式。(请参见https://www.apollographql.com/docs/graphql-tools/schema-stitching了解更多详细信息。(

然后你可以创建你的服务器作为正常

import schema from './graphql/schema';
const server = new GraphQLServer({schema: schema})

最新更新