typescript Svelte中GraphQL查询模板文字的类型安全性?

sr4lhrrt  于 2023-06-24  发布在  TypeScript
关注(0)|答案(1)|浏览(132)

我正在使用graphql-codegen为我的sveltekit项目中的graphql查询生成typescript类型。然而,graphql-codegen似乎无法识别我的svelte文件中模板文字中的查询。
urql docs展示了一个在svelte中使用graphql codegen的示例:

// codegen.ts
const config: CodegenConfig = {
  schema: '<YOUR_GRAPHQL_API_URL>',
  documents: ['src/**/*.svelte'],
  ignoreNoDocuments: true, // for better experience with the watcher
  generates: {
    './src/gql/': {
      preset: 'client',
      plugins: [],
    },
  },
};

export default config;

他们还展示了一个使用react的示例,其中模板字面量中的查询是自动键入的,并声称 “Vue和Svelte绑定的用法保持不变”

import React from 'react';
import { useQuery } from 'urql';

import './App.css';
import Film from './Film';
import { graphql } from '../src/gql';

const allFilmsWithVariablesQueryDocument = graphql(/* GraphQL */ `
  query allFilmsWithVariablesQuery($first: Int!) {
    allFilms(first: $first) {
      edges {
        node {
          ...FilmItem
        }
      }
    }
  }
`);

function App() {
  // `data` is typed!
  const [{ data }] = useQuery({
    query: allFilmsWithVariablesQueryDocument,
    variables: { first: 10 },
  });
  return (
    <div className="App">
      {data && (
        <ul>
          {data.allFilms?.edges?.map(
            (e, i) => e?.node && <Film film={e?.node} key={`film-${i}`} />
          )}
        </ul>
      )}
    </div>
  );
}

export default App;

以下是我的源代码,其中包含一个示例GraphQL查询模板文字:

<!-- src/routes/+page.svelte -->
<script lang="ts">
    import { onMount } from 'svelte';

    import { queryStore, getContextClient, gql } from '@urql/svelte';
    import { getContext } from 'svelte';
    import { graphql } from '../gql';

    const client = getContextClient();

    console.log('Saying hello...');

    const helloQuery = graphql(/* GraphQL */ `
        query {
            hello
        }
    `);

    onMount(async () => {
        const res = await client.query(helloQuery, {}).toPromise();
        console.log('Said hello! response:', res.data);
    });
</script>

我试着从我的codegen配置中删除ignoreNoDocuments,这导致codegen失败,理由是如果不安装svelte2tsx,就无法解析svelte组件中的模板文字。安装svelte 2 tsx后,codegen成功完成,但无法识别我的查询。
不幸的是,我找不到任何人成功地在svelte中键入模板文字查询的例子,但这似乎是可能的。另一种方法是在单独的graphql文件中编写查询,并将生成的输出导入到我的svelte和ts文件中,但这似乎更像是样板文件,而且利用urql缓存和svelte绑定有点不那么直观。
是否可以使用当前的工具在svelte组件中输入GraphQL查询模板文字?它值得吗,或者你会建议一个不同的技术堆栈?

ldioqlga

ldioqlga1#

虽然我还没有找到模板文字的解决方案,但我认为我找到了一个更好的替代方案。
我不知道graphql-codegen在2020年引入了TypedDocumentNodes,它允许你从graphql文档中生成和导入类型化的AST。这已经是一个不错的解决方案了,但是每次更新文档时都必须运行graphql-codegen,然后从生成的文件中将AST导入typescript代码。
我想我找到了一个更好的解决方案。graphql-tag打包了两个用于将GraphQL解析为AST的实用程序,包括一个***webpack加载器来预处理查询***。这将允许您直接从graphql文件导入预处理的AST,在使用graphql-codegen时跳过生成步骤。
graphql-tag文档提到了标准webpack加载器的一些替代方案,包括typescriptbabelreact nativenext jsjest的解决方案。
我还发现了vite-plugin-graphql,它非常适合已经使用vite的sveltekit项目,尽管它自3年前发布以来一直没有更新。相反,我找到了@rollup/plugin-graphql,这是由rollup团队维护的官方插件。vite文档还列出了@rollup/plugin-graphql兼容沿着使用指南。

相关问题