У меня есть узел, экспресс-сервер с использованием 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 });
Это способ сделать это?
Итак, что мне нужно для настройки машинописного текста, чтобы иметь возможность импортировать и создавать схему
Возможный дубликат Ошибка компиляции Typescript с файлами graphql






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, поэтому они могут иметь вес в этом направлении.
Этот ответ решает проблемы, поднятые @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.
Чтение файла как чистого текста, как вы упомянули, - лучший способ сделать это, если вы не используете какой-либо сборщик (например, webpack). Таким образом, вы также можете упростить lint и автоматическое форматирование файлов gql.