GrappleGQL / gatsby-source-wagtail

Plugin for sourcing Gatsby data from Wagtail CMS

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Query for implementation of `StreamFieldInterface` breaks preview

tbrlpld opened this issue · comments

I just discovered that GraphQL queries involving the fragments for implementations of the StreamFieldInterface (like TextBlock or ImageChooserBlock) break the functionality of the preview feature.

A query like this

query ($slug: String) {
  wagtail {
    page(slug: $slug) {
      ... on BlogPage {
        id
        title
        freeformbody {  # this is the StreamField
          id
        }
      }
    }
  }
}

works. But as soon as I add a implementation fragment like so

query ($slug: String) {
  wagtail {
    page(slug: $slug) {
      ... on BlogPage {
        id
        title
        freeformbody {
          id
          ... on TextBlock {
            rawValue
          }
        }
      }
    }
  }
}

then the preview page remains empty. Looking at the developer console I can find the following error messages:

You are using the simple (heuristic) fragment matcher, but your queries contain union or interface types. Apollo Client will not be able to accurately map fragments. To make this error go away, use the IntrospectionFragmentMatcher as described in the docs: https://www.apollographql.com/docs/react/advanced/fragments.html#fragment-matcher

WARNING: heuristic fragment matching going on!

The queries are fine in the GraphiQL interface and the Gatsby development and build pages work too.

The link in the error message itself only leads to a 404 page. I guess the Apollo documentation has been restructured since. I tried to search for keywords from the error message in the documentation and found the following two resources.

It appears that something along the lines of this

import { IntrospectionFragmentMatcher } from 'apollo-cache-inmemory';
import introspectionQueryResultData from './fragmentTypes.json';

... 

const fragmentMatcher = new IntrospectionFragmentMatcher({
  introspectionQueryResultData
});

const cache = new InMemoryCache({ fragmentMatcher });

const client = new ApolloClient({
  cache,
  link: new HttpLink(),
});

would need to be added in the preview.boilerplate.js.

I will give this a shot, but I have to say that I am not experienced with Gatsby plugin nor NPM package development.

In case it is really that simple and solves the issue, I am happy to create a PR, but I assume that this will require some more experienced developers input.

As I was afraid of, I am not even getting an example site running with a local copy of the plugin.

I have tried all three setups mentioned in Creating a Local Plugin | GatsbyJS.
Neither a local /plugins folder nor resolve.require in the gatsby-config.js nor npm link ... work for me.

The first two options result in this error message:

...
  Error: Cannot find module 'gatsby-source-wagtail/pages.js'
...

The file does exist though. Cleaning the plugin directory and the page directory and running npm run build or npm run watch in the plugin repo also have no effect on this.

The npm link ... option results in a different error:

...
 ERROR

Missing onError handler for invocation 'building-schema', error was 'Error: Cannot create as TypeComposer the following value: Query.'. Stacktrace was 'Error: Cannot create as TypeComposer the following value: Query.
    at SchemaComposer.createTempTC (/Users/tibor/1-Projects/gatsby-source-wagtail-preview-issue/example-frontend/node_modules/graphql-compose/lib/SchemaComposer.js:365:11)
    at /Users/tibor/1-Projects/gatsby-source-wagtail-preview-issue/example-frontend/node_modules/gatsby/dist/schema/schema.js:708:36
    at Array.forEach (<anonymous>)
    at addThirdPartySchemas (/Users/tibor/1-Projects/gatsby-source-wagtail-preview-issue/example-frontend/node_modules/gatsby/dist/schema/schema.js:706:21)
    at updateSchemaComposer (/Users/tibor/1-Projects/gatsby-source-wagtail-preview-issue/example-frontend/node_modules/gatsby/dist/schema/schema.js:210:9)
    at async buildSchema (/Users/tibor/1-Projects/gatsby-source-wagtail-preview-issue/example-frontend/node_modules/gatsby/dist/schema/schema.js:91:3)
    at async build (/Users/tibor/1-Projects/gatsby-source-wagtail-preview-issue/example-frontend/node_modules/gatsby/dist/schema/index.js:141:18)
    at async buildSchema (/Users/tibor/1-Projects/gatsby-source-wagtail-preview-issue/example-frontend/node_modules/gatsby/dist/services/build-schema.js:20:3)'

...

Not sure how to proceed here.

@NathHorrigan @zerolab How do you set up the development for this package?

Also, can you even reproduce the issue?

Hi @tbrlpld ,

I install via NPM most of the time. Does that not work?

What does your gatsby-nodes.js look like currently?

Hi @NathHorrigan

I install via NPM most of the time. Does that not work?

Install the local copy of the plugin? How do you do that? Just npm install ../path/to/plugin? Does that automatically reflect changes in the example project when you update the plugin source code?

My gatsby-node.js in the example project is pretty much just the snippet from the README:

const { createWagtailPages } = require('gatsby-source-wagtail/pages.js')

exports.createPages = ({ graphql, actions }) => {
  return createWagtailPages({
    'home.BlogPage': 'templates/blog.js'
  }, graphql, actions, [])
}

No, I normally develop separately and then install via a Github link. It's not ideal but I haven't been able to work on a development version without dependency conflicts.

}, graphql, actions, [])

That array at the end is where you provide the path to fragment files. This solves the issue where they aren't available during preview.

Let me know if that helps :)

No, I normally develop separately and then install via a Github link. It's not ideal but I haven't been able to work on a development version without dependency conflicts.

Gotcha. So no immediate feedback on the changes. You always have to update the plugin in the example project to test changes.

I will give that a shot. I have not implemented any custom fragments in my example site. So would that be the path to the fragments.json in gatsby-source-wagtail? Should that maybe be changed in the definition of the createWagtailPages function?

That array at the end is where you provide the path to fragment files. This solves the issue where they aren't available during preview.

The issue is not occurring with custom fragments. I get the issue when trying to use the provided StreamFieldInterface fragments (like ... on ImageChooseBlock).

Are you able to reproduce this?

I have tried passing the gatsby-source-wagtail files fragements.js or the fragmentTypes.json in different ways, but I keep getting Error: Cannot find module ... in the preview page.
gatsby-node.js in the example frontend:

const { createWagtailPages } = require('gatsby-source-wagtail/pages.js')

exports.createPages = ({ graphql, actions }) => {
  return createWagtailPages({
    'home.BlogPage': 'templates/blog.js'
  }, graphql, actions, ['gatsby-source-wagtail/fragments.js'])
}

I guess I am not quite understanding what you mean I should be passing into that array.

@NathHorrigan the solution that was proposed in the Apollo error message fixed the issue! 😄🎉

I have created PR #22 for your consideration 😊

Thank you @tbrlpld !