gatsby-plugin-typegen icon indicating copy to clipboard operation
gatsby-plugin-typegen copied to clipboard

Exported schemas in .ts files are not generated

Open ecklf opened this issue 5 years ago • 18 comments

Hi, trying to migrate from 0.2.0 to 1.1.2 but it doesn't seem my type for an exported query schema gets exported anymore (file is in src/lib/ folder). Under 0.2.0 the following query:

export const schema = graphql`
  query Posts {
    allMdx(sort: { order: DESC, fields: [frontmatter___date] }) {
      edges {
        node {
          id
          excerpt(pruneLength: 250)
          frontmatter {
            title
            slug
            categories
            tags
          }
          body
        }
      }
    }
  }
`

would result in the following schema generation

export type PostsQuery = (
  { __typename?: 'Query' }
  & { allMdx: (
    { __typename?: 'MdxConnection' }
    & { edges: Array<(
      { __typename?: 'MdxEdge' }
      & { node: (
        { __typename?: 'Mdx' }
        & Pick<Mdx, 'id' | 'excerpt' | 'body'>
        & { frontmatter: Maybe<(
          { __typename?: 'MdxFrontmatter' }
          & Pick<MdxFrontmatter, 'title' | 'slug' | 'categories' | 'tags'>
        )> }
      ) }
    )> }
  ) }
);

What I am doing wrong here, are there breaking changes?

ecklf avatar Mar 07 '20 14:03 ecklf

Hi @impulse.

Yes, this plugin was changed in v1.0, to generate code for queries that actually using by Gatsby instead of directory globs.

So, if you didn't call createPage action with the path in gatsby-node, the plugin don't actually know about the query because Gatsby doesn't use it.

cometkim avatar Mar 08 '20 11:03 cometkim

@cometkim thanks for the quick response.

Will the solution you described here solve this? I think the culprit is that I still use tsnode and didn't make the switch to it yet.

ecklf avatar Mar 09 '20 14:03 ecklf

Will the solution you described here solve this? I think the culprit is that I still use tsnode and didn't make the switch to it yet.

@impulse Unfortunately, It wouldn't. The important point is that your queries are under the src/lib/folder path. Queries not used by the Gatsby compiler are also not used by this plugin. So you need to change your page queries to be actually exported from the page component.

BTW, maybe you should check out the https://github.com/Js-Brecht/gatsby-plugin-ts-config by @Js-Brecht. There is also a neat example that is actually using typegen and ts-node.

A discussion for using ts-config and typegen is open here: #48

cometkim avatar Mar 09 '20 15:03 cometkim

BTW, maybe you should check out the https://github.com/Js-Brecht/gatsby-plugin-ts-config by @Js-Brecht. There is also a neat example that is actually using typegen and ts-node.

Just an FYI, the ts-config branch of that starter uses the ts-config plugin, so it's a decent example of using the plugin itself. The master branch just uses ts-node directly in the gatsby-config, so it's basically a user driven example. The ts-config plugin does work to make sure it is only responsible for the gatsby-* files, and nothing else, to make sure it doesn't interfere with Gatsby's build.

The important point is that your queries are under the src/lib/folder path. Queries not used by the Gatsby compiler are also not used by this plugin.

@cometkim correct me if I'm wrong, but shouldn't Gatsby pick up all queries that are under the src directory (reference)? If I replicate the glob usage that Gatsby utilizes, I do get all *.ts files anywhere I put them in src.

Js-Brecht avatar Mar 09 '20 16:03 Js-Brecht

@cometkim correct me if I'm wrong, but shouldn't Gatsby pick up all queries that are under the src directory (reference)? If I replicate the glob usage that Gatsby utilizes, I do get all *.ts files anywhere I put them in src.

https://github.com/gatsbyjs/gatsby/blob/dd344ac4ea/packages/gatsby/src/query/file-parser.js#L142

@Js-Brecht It's actually collecting some specific nodes. There seems to be a separate place to track the gatsby-node file, but I haven't figured it out yet.

cometkim avatar Mar 12 '20 15:03 cometkim

@cometkim I honestly don't think it extracts queries from gatsby-node. I believe those queries using the Gatsby graphql() function in gatsby-node are executed imperatively, when the particular endpoint export is called.

The point I was trying to make here is that if the queries @impulse is trying to generate types for are under the src directory, and they use graphql tag like he shows in the OP, then they should be picked up by Gatsby. Gatsby will complain about them, because they aren't being used by anything under src, but they should still trigger your plugin to process them.

For example, I just created a brand new project, and added a query (isolated; not being used by anything):

// src/lib/schema.ts
import { graphql } from 'gatsby';

export const schema = graphql`
  query Posts {
    allMdx(
      sort: { fields: [frontmatter___date], order: DESC }
      limit: 1000
    ) {
      edges {
        node {
          id
          fields {
            slug
          }
          frontmatter {
            title
          }
          body
        }
      }
    }
  }
`

Then I run gatsby build with your plugin (v1.1.2), and I get this type generated:

// formatted for reading purposes
export type PostsQuery = {
  readonly allMdx: {
    readonly edges: ReadonlyArray<{
      readonly node: (
        Pick<Mdx, 'id' | 'body'>
        & {
          readonly fields: Maybe<Pick<MdxFields, 'slug'>>,
          readonly frontmatter: Maybe<Pick<MdxFrontmatter, 'title'>>
        }
      )
    }>
  }
};

Js-Brecht avatar Mar 12 '20 16:03 Js-Brecht

@impulse Could you please confirm if the same problem occurs in the last version(2.1.0)?

cometkim avatar Apr 15 '20 22:04 cometkim

@cometkim still the same issue and I think the namespace change seems to have broken the ts-node approach completely (getting a cannot find namespace GatsbyTypes error). @Js-Brecht is your plugin affected by this?

ecklf avatar Apr 16 '20 08:04 ecklf

@impulse Can you share your typegen plugin config and the tsconfig?

cometkim avatar Apr 16 '20 08:04 cometkim

@cometkim just added typegen to the plugins array tsconfig is the following:

// tsconfig.json
{
  "compilerOptions": {
    "target": "es5" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */,
    "module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */,
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ] /* Specify library files to be included in the compilation. */,
    "allowJs": true /* Allow javascript files to be compiled. */,
    "checkJs": true /* Report errors in .js files. */,
    "jsx": "react" /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */,
    "noEmit": true /* Do not emit outputs. */,
    "importHelpers": true /* Import emit helpers from 'tslib'. */,
    "isolatedModules": false /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */,
    "strict": true /* Enable all strict type-checking options. */,
    "moduleResolution": "node" /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */,
    "resolveJsonModule": true,
    "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */,
    "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
  },
  "include": ["./src/**/*"]
}

ecklf avatar Apr 16 '20 08:04 ecklf

@impulse i use gatsby-plugin-ts-config and gatsby-plugin-typegen v2 together without any issues.

When switching to v2, I did have to make sure that the types generated by gatsby-plugin-typegen were covered in the include property in tsconfig. IIRC, that was all it took.

Js-Brecht avatar Apr 16 '20 15:04 Js-Brecht

Hey @impulse,

That's not only exporting query Posts {...}, but also importing it and use in your GatsbyJS project right?

Can you share code so I can reproduce the problem? Or share the read permission for a while If it's private?

cometkim avatar May 02 '20 21:05 cometkim

I'll create a repo that reproduces the issue tomorrow 👍

ecklf avatar May 04 '20 20:05 ecklf

As promised: reproduction repo (see lib/createPages).

I also tried specifying the project in ts-node because I already have the entire src folder (where __generated__ is) included in my tsconfig.

require("ts-node").register({
    project: './tsconfig.json'
}

Unfortunately I still get Cannot find namespace 'GatsbyTypes'.

ecklf avatar May 05 '20 19:05 ecklf

@impulse

Oh, I see.

Actually, this plugin has not yet officially supported gatsby-node. :sweat_smile:

Before the v1 release, codegen generated regardless of Gatsby since it had used glob pattern for it. But now it effectively performs codegen only for queries that gatsby actually tracks (not including gtsby-node).

So far, I have focused on improving DX for creating components, and
now I have to conduct case studies for the next release:

  • supporting gatsby-node and schema customization
  • improving DX with page queries

There are several related open issues.

  • #27
  • #48
  • #74

You can still use the codegen CLI for an unsupported part like this (for example, apollo-client)

I won't include types from gatsby-node or something else until I find a reason and way to handle it effectively.

Because the goal of this plugin is to improve the real DX. I have made this after I was suffered from a heavy development environment in a project that runs a lot of codegen processes.

I'm closing this but I enjoy hearing your case. Any feedback or suggestions are welcome!

cometkim avatar May 05 '20 21:05 cometkim

Unfortunately I still get Cannot find namespace 'GatsbyTypes'.

~~I will try to figure it out in a few days.~~

Well, I just tried to repro this

➜  yarn tsc --noEmit --skipLibCheck
yarn run v1.22.4
$ /home/cometkim/Workspace/tmp/typegen-error/node_modules/.bin/tsc --noEmit --skipLibCheck
src/components/header.js:5:19 - error TS7031: Binding element 'siteTitle' implicitly has an 'any' type.

5 const Header = ({ siteTitle }) => (
                    ~~~~~~~~~

src/components/layout.js:15:19 - error TS7031: Binding element 'children' implicitly has an 'any' type.

15 const Layout = ({ children }) => {
                     ~~~~~~~~

src/components/seo.js:10:24 - error TS7016: Could not find a declaration file for module 'react-helmet'. '/home/cometkim/Workspace/tmp/typegen-error/node_modules/react-helmet/lib/Helmet.js' implicitly has an 'any' type.
  Try `npm install @types/react-helmet` if it exists or add a new declaration (.d.ts) file containing `declare module 'react-helmet';`

10 import { Helmet } from "react-helmet"
                          ~~~~~~~~~~~~~~

src/components/seo.js:13:16 - error TS7031: Binding element 'description' implicitly has an 'any' type.

13 function SEO({ description, lang, meta, title }) {
                  ~~~~~~~~~~~

src/components/seo.js:13:29 - error TS7031: Binding element 'lang' implicitly has an 'any' type.

13 function SEO({ description, lang, meta, title }) {
                               ~~~~

src/components/seo.js:13:35 - error TS7031: Binding element 'meta' implicitly has an 'any' type.

13 function SEO({ description, lang, meta, title }) {
                                     ~~~~

src/components/seo.js:13:41 - error TS7031: Binding element 'title' implicitly has an 'any' type.

13 function SEO({ description, lang, meta, title }) {
                                           ~~~~~

src/lib/createPages.ts:41:49 - error TS2694: Namespace 'GatsbyTypes' has no exported member 'PostsQuery'.

41   const result = await graphqlQuery<GatsbyTypes.PostsQuery>(print(schema))
                                                   ~~~~~~~~~~


Found 8 errors.

error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

This is all I've got after clone the repo, install dependencies and run tsc --noEmit --skipLibCheck and there is no error you mentioned.

Make sure your IDE settings are referencing the tsconfig.json and tsc version of the workspace correctly.

cometkim avatar May 05 '20 21:05 cometkim

Before the v1 release, codegen generated regardless of Gatsby since it had used glob pattern for it. But now it effectively performs codegen only for queries that gatsby actually tracks (not including gtsby-node).

Fair enough, I'll just generate this manually then.

Make sure your IDE settings are referencing the tsconfig.json and tsc version of the workspace correctly.

I get the same error as you when running tsc. The error I've mentioned happens when running gatsby develop (sorry should have specified)

ecklf avatar May 06 '20 05:05 ecklf

Hey folks, I just wanted to mention that I resolved my " Cannot find namespace 'GatsbyTypes'." problem by adding

import "./src/__generated__/gatsby-types";

to my gatsby-config.ts.

I hope it helps somebody who lands here googling this error like I did today 😊

hasparus avatar Oct 22 '20 16:10 hasparus