Deno で graphql-codegen する
はじめに
The Guild がメンテナンスしている https://github.com/dotansimha/graphql-code-generator は、GraphQL の Schema から TypeScript を生成できたりします。
フロントエンドでもバックエンドでも重宝する超便利ライブラリなのですが、Deno で使おうと思った時「あれ。どうやるんだっけ。」となったので調べてみました。
(そこだけ npm 使えばいいやん。という話かもしれないですが、統一できた方がなんか気持ち良かったので ...)
TL;DR
Deno で graphql-codegen を利用したい際には、@graphql-codegen/core
を利用しスクリプトを書いて実行する。
deno run --allow-write https://raw.githubusercontent.com/motoya-k/graphql-scalar-sample/main/codegen.example.ts
【試行錯誤】 Deno で graphql-codegen する方法を考える
Deno CLI の install コマンドを利用する
Deno CLI では install
コマンドが提供されています。
このコマンドによりローカル環境にシェルスクリプトが作成され、特定の名前でスクリプトを実行できるようになります。
例えば、
deno install --allow-net --allow-read -n myfs https://deno.land/std/http/file_server.ts -- -p 8080
とすると、
myfs
> Listening on http://localhost:8080/
でファイルサーバーが http://localhost:8080 で立ち上がります。
これを利用して、@graphql-codegen/cli
を実行しようとしてみます。
deno install -A -n graphql-codegen "npm:@graphql-codegen/cli@5.0.0"
> ✅ Successfully installed graphql-codegen
> /Users/motoyakondo/.deno/bin/graphql-codegen
インストールはうまくいったので実行してみます。
graphql-codegen
> error: '***/Caches/deno/npm/registry.npmjs.org/@graphql-codegen/cli/5.0.0/package.json' did not have a bin entry for '@graphql-codegen/cli'
>
> Possibilities:
> * npm:@graphql-codegen/cli@5.0.0/gql-gen
> * npm:@graphql-codegen/cli@5.0.0/graphql-codegen
> * npm:@graphql-codegen/cli@5.0.0/graphql-code-generator
> * npm:@graphql-codegen/cli@5.0.0/graphql-codegen-esm
となってしまい、実行できません。
試しに Possibilities
で提示されているエントリポイントを利用してみます。
どれも SyntaxError: await is only valid in async functions and the top level bodies of modules
というエラーが出てしまいうまくいきませんでした。
無念 ...。
Script を書いて実行する
困ったなと思って Issue を漁っていたところ以下を発見しました。
@graphql-codegen/cli
ではなく @graphql-codegen/core
の方を利用して、スクリプトを書けば良いという話でした。
以下のようなスクリプトを用意し、このファイルを実行します。
import { codegen } from "npm:@graphql-codegen/core@4.0.0";
import * as typescriptResolversPlugin from "npm:@graphql-codegen/typescript-resolvers@2.7.7";
import { TypeScriptResolversPluginConfig } from "npm:@graphql-codegen/typescript-resolvers@2.7.7";
import * as typescriptPlugin from "npm:@graphql-codegen/typescript@2.8.2";
import { TypeScriptPluginConfig } from "npm:@graphql-codegen/typescript@2.8.2";
import { GraphQLSchema, buildSchema, parse, printSchema } from "npm:graphql@16.8.1";
const typeDefs = /* GraphQL */`
type User {
id: ID!
name: String!
age: Int!
}
type Query {
users: [User!]!
user(id: ID!): User
}
type Mutation {
createUser(name: String!, age: Int!): User!
}
`
const schema: GraphQLSchema = buildSchema(typeDefs);
const outputFile = "./resolvers_types.ts";
const typescriptPluginConfig: TypeScriptPluginConfig = {}
const typescriptResolversPluginConfig: TypeScriptResolversPluginConfig = {}
const config: Parameters<typeof codegen>[number] = {
documents: [],
config: {},
filename: outputFile,
schema: parse(printSchema(schema)),
plugins: [
{
// ref: https://the-guild.dev/graphql/codegen/plugins/typescript/typescript
typescript: typescriptPluginConfig,
},
{
// ref: https://the-guild.dev/graphql/codegen/plugins/typescript/typescript-resolvers
typescriptResolvers: typescriptResolversPluginConfig,
},
],
pluginMap: {
typescript: typescriptPlugin,
typescriptResolvers: typescriptResolversPlugin,
},
};
const output = await codegen(config);
await Deno.writeFile(outputFile, new TextEncoder().encode(output));
console.log("Outputs generated! 🚀");
Deno のカスタムコマンドを登録しておくと使い勝手が良いかもしれません。
{
"tasks": {
"codegen": "deno run -A codegen.ts"
}
}
deno task codegen
この方法では無事、型ファイルを生成できました!良かった😊
手元で Deno を動かせる方は、以下のコマンドで実際の動作を確認することができます。
deno run --allow-write https://raw.githubusercontent.com/motoya-k/graphql-scalar-sample/main/codegen.example.ts
Discussion