#typescript #webpack #graphql #graphql-js #graphql-codegen
#typescript #webpack #graphql #graphql-js #graphql-codegen
Вопрос:
У меня есть некоторые операции (запрос / мутация, а иногда и некоторые фрагменты в нижней части файла), определенные в .gql
файлах, иногда более одного в одном файле.
Я хотел бы импортировать их в свои файлы JS / TS, возможно, также сгенерировать соответствующие типы для TypeScript.
Я настроил здесь пример из 3 файлов:
https://gist.github.com/balazsorban44/352d5295f604fb4274bfc934937737a1
queries.gql
Файл является исходным кодом. Они должны генерировать соответствующие типы модулей в файле (см. generated-types.d.ts
), чтобы я мог импортировать их в свой index.ts
файл и использовать его для выполнения вызовов graphql с помощью простого fetch
.
То, что я пробовал до сих пор, — это следующие инструменты / пакеты:
Насколько я могу судить, ни одно из вышеперечисленных не поддерживает несколько операций для каждого файла, экспортируемого в виде строки, только несколько операций в виде DocumentNode или весь файл в виде строки.
- graphql-codegen/typescript-graphql-files-modules выводит только типы DocumentNode, нет возможности изменить тип на string
Дайте мне знать, если возникнут еще какие-нибудь вопросы.
Ответ №1:
Решение с использованием документов-загрузка graphql-tools и separateOperations — служебная функция для разделения AST. Вот шаги:
- загрузка документов из
.gql
файлов - Разделите этот всеобъемлющий AST на отдельные AST, которые представляют каждую операцию, которая может быть отправлена на сервер изолированно.
- Преобразование
DocumentNode
(AST) в строку с помощью функции печатиgraphql
пакета.
Например.
queries.gql
:
query Something {
name
id
}
query SomethingElse($email: String!) {
somethingelse(email: $email) {
phone
...SomeFragment
}
}
fragment SomeFragment on User {
email
address
}
index.ts
:
import { loadDocumentsSync } from '@graphql-tools/load';
import { GraphQLFileLoader } from '@graphql-tools/graphql-file-loader';
import path from 'path';
import { separateOperations, print, buildSchema } from 'graphql';
import express from 'express';
import { graphqlHTTP } from 'express-graphql';
import fetch from 'node-fetch';
const documents = loadDocumentsSync(path.resolve(__dirname, './queries.gql'), {
loaders: [new GraphQLFileLoader()],
});
const { Something, SomethingElse } = separateOperations(documents[0].document!);
console.log(print(Something));
console.log(print(SomethingElse));
// server
const schema = buildSchema(`
type User {
id: ID!
name: String
email: String
address: String
phone: String
}
type Query {
somethingelse(email: String!): User
Something: User
}
`);
const root = {
somethingelse({ email }) {
return { id: 1, name: 'teresa teng', email, address: 'Japan', phone: '123' };
},
};
const app = express();
app.use(
'/graphql',
graphqlHTTP({
schema: schema,
rootValue: root,
graphiql: true,
}),
);
app.listen(4000, () => console.log('graphql server running on localhost 4000'));
// test
fetch('http://localhost:4000/graphql', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ query: print(SomethingElse), variables: { email: 'teresa.teng@gmail.com' } }),
})
.then((res) => res.json())
.then((res) => console.log(res))
.catch(console.error);
Результат выполнения:
query Something {
name
id
}
query SomethingElse($email: String!) {
somethingelse(email: $email) {
phone
...SomeFragment
}
}
fragment SomeFragment on User {
email
address
}
graphql server running on localhost 4000
{ data:
{ somethingelse:
{ phone: '123',
email: 'teresa.teng@gmail.com',
address: 'Japan' } } }
Кстати, если предоставленные вами инструменты / пакеты могут загружать документы из .gql
файлов, вы можете использовать его вместо использования graphql-tools
. Остальные шаги те же.