Как использовать .graphql в проекте узла машинописного текста без веб-пакета

У меня есть узел, экспресс-сервер с использованием expressGraphql. Я пытаюсь объявить определение типа для graphql в файле .graphql или .gql, потому что по мере увеличения типа становится трудно читать 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

Cannot find module './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.

femanso 26.09.2018 08:42

Возможный дубликат Ошибка компиляции Typescript с файлами graphql

Matias Olivera 12.12.2018 00:27
Зод: сила проверки и преобразования данных
Зод: сила проверки и преобразования данных
Сегодня я хочу познакомить вас с библиотекой Zod и раскрыть некоторые ее особенности, например, возможности валидации и трансформации данных, а также...
Как заставить Remix работать с Mantine и Cloudflare Pages/Workers
Как заставить Remix работать с Mantine и Cloudflare Pages/Workers
Мне нравится библиотека Mantine Component , но заставить ее работать без проблем с Remix бывает непросто.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
TypeScript против JavaScript
TypeScript против JavaScript
TypeScript vs JavaScript - в чем различия и какой из них выбрать?
Синхронизация localStorage в масштабах всего приложения с помощью пользовательского реактивного хука useLocalStorage
Синхронизация localStorage в масштабах всего приложения с помощью пользовательского реактивного хука useLocalStorage
Не все нужно хранить на стороне сервера. Иногда все, что вам нужно, это постоянное хранилище на стороне клиента для хранения уникальных для клиента...
Что такое ленивая загрузка в Angular и как ее применять
Что такое ленивая загрузка в Angular и как ее применять
Ленивая загрузка - это техника, используемая в Angular для повышения производительности приложения путем загрузки модулей только тогда, когда они...
9
2
5 281
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

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 26.07.2018 00:39

Я не видел отправленного вами сообщения об ошибке. Вы его снова удалили?

Mikael Lirbank 26.07.2018 01:31

Не уверен, что это лучший способ сделать это. Я использовал эти два метода в нескольких приложениях, над которыми работал. В моем текущем проекте я использую файлы .graphql и читаю их с помощью fs.readFile. Я бы сказал, это вопрос предпочтений. Некоторые инструменты разработки лучше справляются с простыми текстовыми файлами .graphql, поэтому они могут иметь вес в этом направлении.

Mikael Lirbank 26.07.2018 01:34

Этот ответ решает проблемы, поднятые @leogoesger. Это модульный подход к созданию схем с использованием файлов .graphql без необходимости определения нескольких вызовов makeExecutableSchema.

Для работы структура папок должна выглядеть примерно так:


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

schema.graphql содержит все определения вашего типа. Файлы "feature" Resolver содержат ваши преобразователи, которые представляют собой объект, содержащий ваши запросы и изменения.

Внутри вашего файла 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 для создания единой схемы GraphQL из нескольких API. (Подробнее см. https://www.apollographql.com/docs/graphql-tools/schema-stitching.)

Затем вы можете создать свой сервер как обычно

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

Вы можете использовать https://github.com/ardatan/graphql-import-node, чтобы решить эту проблему без веб-пакета.

Установите с помощью yarn add graphql-import-node или npm 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/register с mocha -r для своих тестов.

Вам также может потребоваться добавить "esModuleInterop": true в параметры вашего компилятора в tsconfig.json.

Другие вопросы по теме