【问题标题】:how to use .graphql in a typescript node project without webpack如何在没有 webpack 的打字稿节点项目中使用 .graphql
【发布时间】:2019-01-02 15:55:39
【问题描述】:

我有一个节点,使用 expressGraphql 表达服务器。我试图在.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 });

这是这样做的方式吗?

那么我需要如何配置打字稿才能导入和构建架构

【问题讨论】:

  • 正如您所提到的,如果您不使用任何捆绑程序(如 webpack),那么将文件作为纯文本读取是最好的方法。这样,您还可以更轻松地 lint 和自动格式化 gql 文件

标签: typescript graphql


【解决方案1】:

您可以使用https://github.com/ardatan/graphql-import-node 来解决这个问题,而无需使用 webpack。

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

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

或者像这样将它导入你的文件顶部:

import "graphql-import-node";

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

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

【讨论】:

    【解决方案2】:

    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,
    ] });
    

    【讨论】:

    • 这样做真的是最好的吗?这意味着我必须对我定义的每个类型文件使用该方法
    • 我没有看到您发布的错误消息。你又删除了吗?
    • 不确定这是不是最好的方法。在我一直在开发的一些应用程序中,我一直在这两种方法之间进行切换。在我当前的项目中,我使用 .graphql 文件并使用 fs.readFile 读取它们。我会说这是一个偏好问题。一些开发工具更擅长处理纯 .graphql 文本文件,因此可能会在这个方向上发挥作用。
    【解决方案3】:

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

    文件夹结构应如下所示:

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

    schema.graphql 包含所有类型定义。 “功能”解析器文件包含您的解析器,它是一个包含您的查询和突变的对象。

    在您的 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})
    

    【讨论】:

      猜你喜欢
      • 2022-01-05
      • 2021-12-25
      • 2014-04-19
      • 1970-01-01
      • 2018-11-21
      • 2020-06-20
      • 1970-01-01
      • 2018-04-03
      相关资源
      最近更新 更多