gatsby-typescript
gatsby-typescript copied to clipboard
Feature request: gatsby-node codegen
Objective
The following is a feature request to add codegen for gatsby-node related typescript files so that calls to graphql
via the createPages
node API are typed.
My gatsby-node.js
file looked something like this:
// gatsby-node.js
const nodeTsConfig = {/* ... */};
require('ts-node').register(nodeTsConfig);
const createShopPage = require('./create-shop-page.ts').default;
exports.createPages = async args => {
await createShopPage(args);
};
I use ts-node
to load typescript files from gatsby-node.js
.
The following 👇 is an example typescript file imported from gatsby-node.js
// create-shop-page.ts
import { CreatePagesArgs } from 'gatsby';
async function createShopPage({
actions: { createPage },
graphql,
}: CreatePagesArgs) {
// 👇 the goal is to generate types for this
const { data } = await graphql(`
query CreateShopPage {
wpgraphql {
products(first: 5) {
nodes {
name
slug
}
}
}
}
`);
// ...
}
export default createShopPage;
As stated in the comment above, the goal of this feature request is to add types for data
.
Assessment
The Magic Comment
After a lot of digging and even opening up other related feature requests, I found out that graphql-code-generator
already supports generating types from inside gatsby-node
's await graphql(/* ... */)
calls via a "magic comment".
This means that simply adding the comment /* GraphQL */
inline to the graphql(/* ... */)
call will make graphql-codegen
create types for the CreateShopPage
query:
// create-shop-page.ts
import { CreatePagesArgs } from 'gatsby';
async function createShopPage({
actions: { createPage },
graphql,
}: CreatePagesArgs) {
// adding this enables types to be generated for `CreateShopPage`
// 👇
const { data } = await graphql(/* GraphQL */ `
query CreateShopPage {
wpgraphql {
products(first: 5) {
nodes {
name
slug
}
}
}
}
`);
// ...
}
export default createShopPage;
And additionally, the next release of graphql-codegen
will make it so that you don't need the magic comment.
Issues with onPostBootstrap
The current implementation runs codegen after bootstrapping via onPostBootstrap
, and the createPages
is run before onPostBoostrap
.
This is an issue because if there are types generated that are needed to create pages, then those types will not have been generated yet (via onPostBoostrap
).
Recommendations
- Add some documentation saying that
gatsby-node
codegen is supported via the "magic comment" (until the nextgraphql-codegen
is released). - Move the codegen from
onPostBootstrap
tocreatePages
. I currently have this working by running some code duringcreatePages
before Irequire(/* ... */)
the typescript file.
My gatsby-node.js
currently looks like this:
const codeGenGatsbyNode = require('./code-gen-gatsby-node');
const nodeTsConfig = require('./src/create-pages/tsconfig.json');
require('ts-node').register(nodeTsConfig);
exports.createPages = async args => {
await codeGenGatsbyNode(args);
const createPages = require('./src/create-pages').default;
return createPages(args);
};
-
codeGenGatsbyNode
runs code gen -
create-pages
is a typescript file that uses the generated types
Let me know what you think! I'd be willing to work on this feature if you see fit.
Thanks a bunch!
Hi @ricokahler, thank you very much for this thoughtful feature request.
I think this feature is aligned with another one I've been working on (#4). The end goal is to bring the same reloading codegen in src
to gatsby-node.ts
.
The current gatsby-plugin-graphql-codegen plugin is hooked into Gatsby's watch process, which as you know, doesn't watch gatsby-* files.
I think we may want to create a separate watcher for gatsby-* files. I've been working toward this on another plugin: gatsby-plugin-node-reload
Let me think a bit more about this & give you a better reply soon (I'm excited to have others work on this repo!). In the mean time, please let me know if you have any more thoughts. Thanks again!
Thanks for getting back to me! This is a great project and by far the best TS plugin for gatsby 💯
Let me think a bit more about this & give you a better reply soon (I'm excited to have others work on this repo!). In the mean time, please let me know if you have any more thoughts. Thanks again!
Take your time. I'm not exactly sure my above recommendation makes sense but it's an idea to get us started at least.
I think we may want to create a separate watcher for gatsby-* files. I've been working toward this on another plugin: gatsby-plugin-node-reload
I actually wasn't considering watching and reloading the node side of things. The DX I imagined for this plugin involved restarting gatsby for any node-related changes (since that's more or less how we have to do regardless of codegen), but now that you mention it, I would love if it were actually watching and reloading! That's big improvement to gatsby regardless of codegen.
If your gatsby-plugin-node-reload
project is working well then I think it make sense to integrate codegen with that and its own lifecycles (if that even makes sense) but if it's not ready yet then I think it makes to keep the scope limited to codegen on startup only for node-related types.