Hi, I have a project with some Json as data source: I added the gatsby-plugin-schema-snapshot plugin to speed up my build time and I saw that the images served by the gatsby-image component stopped delivering the WebP picture source.
Here a demo of the issue: https://codesandbox.io/s/infallible-snow-i60fj
I changed the image component to get the image childImage field querying the Json source (in the data directory) instead of querying the file system directly.
The source with the WebP format is missing:
.
I don't knpw if it's correlated but during the build I have this warning message:
The type `File` does not explicitly define the field `childDataJson`.
On types with the `@dontInfer` directive, or with the `infer` extension set to
`false`, automatically adding fields for children types is deprecated.
In Gatsby v3, only children fields explicitly set with the `childOf` extension
Thanks
valse
This is certainly a bug that I can reproduce.
As a workaround (for now), you can exclude gatsby-transformer-sharp from snapshot plugin:
{
resolve: `gatsby-plugin-schema-snapshot`,
options: {
update: true,
exclude: {
plugins: [`gatsby-transformer-sharp`],
},
},
},
Which seems to make it work again.
I'm not sure where to attribute this bug to. With snapshot enabled (and not excluding types from sharp transformer), we get following types in schema:
type ImageSharpFluid {
base64: String
tracedSVG: String
aspectRatio: Float!
src: String!
srcSet: String!
srcWebp: String
srcSetWebp: String
sizes: String!
originalImg: String
originalName: String
presentationWidth: Int
presentationHeight: Int
}
type ImageSharp implements Node @childOf(mimeTypes: [], types: ["File"], many: false) @dontInfer {
# removed fields other than "fluid" for brevity [...]
fluid(
maxWidth: Int
maxHeight: Int
base64Width: Int
grayscale: Boolean = false
jpegProgressive: Boolean = true
pngCompressionSpeed: Int = 4
duotone: DuotoneGradient
traceSVG: Potrace
quality: Int
jpegQuality: Int
pngQuality: Int
webpQuality: Int
toFormat: ImageFormat = NO_CHANGE
toFormatBase64: ImageFormat = NO_CHANGE
cropFocus: ImageCropFocus = ATTENTION
fit: ImageFit = COVER
background: String = "rgba(0,0,0,1)"
rotate: Int = 0
trim: Float = 0
sizes: String = ""
"""
A list of image widths to be generated. Example: [ 200, 340, 520, 890 ]
"""
srcSetBreakpoints: [Int] = []
): ImageSharpFluid
}
Now, resolver for fluid field works fine ( https://github.com/gatsbyjs/gatsby/blob/08d63c5e4ed25e9315101dec4fdb98186c527927/packages/gatsby-transformer-sharp/src/customize-schema.js#L357-L375 ), but resolver for srcWebp (and probably rest of those resolvers on field of ImageSharpFluid type, I just checked one) is not being hit ( https://github.com/gatsbyjs/gatsby/blob/08d63c5e4ed25e9315101dec4fdb98186c527927/packages/gatsby-transformer-sharp/src/customize-schema.js#L236-L252 ). So my gut tells me default resolver is used and because there is no actual srcWebp on object return by fluid - this just make it null?
My guess - ImageSharp type is defined with schema.buildObjectType which seems to play nicely with schema customization (so resolver is attached to type/field defined by schema.gql), while ImageSharpFluid is created using vanilla graphql-js(new GraphQLObjectType({ ... })) which potentially doesn't play nicely?
Thought @vladar?
@pieh This is another rabbit hole %) But I think I've found the root of the problem.
The issue is that the type ImageSharpFluid is created inline as a part of ImageSharp type definition:
In other words when we call createTypes(typeDefs) the type ImageSharpFluid is not in the list of typeDefs. It just sits somewhere deep inside ImageSharp type definition.
It works as long as you don't provide another typeDef for this type (we do this here in snapshot plugin). So instead of merging two typeDefs we rewrite the old typeDef with a new one created from AST (which doesn't have any custom resolvers).
We do this because we don't even know that there is an old ImageSharpFluid typeDef - it is not on our list.
I think the only way to fall into this trap is by using native GraphQL type definitions with schema csutomization. Type builders and AST probably don't have this problem (as you have to add all types to typeDefs directly).
So the unfortunate outcome of this is that we must additionally recursively walk through all fields and manually add any types defined inline into typeDefs.
(I personally think we should probably have fewer options for type definition formats in schema customization API but that's obviously not gonna happen anytime soon for BC and convenience reasons)
@valse This is a very rare and unfortunate edge case and the workaround suggested by @pieh should work for you for now. Still, we must address it in the core as it is a bug.
Yes I confirm that the workaround solve the problem, thanks: could I ignore the "File" warning too?
For the file warning - you could add the following to gatsby-node.js:
// in site's gatsby-node.js:
exports.createSchemaCustomization = ({ actions }) => {
const typeDefs = `
type DataJson implements Node @childOf(types: ["File"]) {
id
}
`
actions.createTypes(typeDefs)
}
This should fix the warning. There is a bit more context on this in #19674