gatsbyjs / gatsby

The best React-based framework with performance, scalability and security built in.
https://www.gatsbyjs.com
MIT License
55.29k stars 10.31k forks source link

Warning on build when GraphQL query is shadowed #23729

Open SOHELAHMED7 opened 4 years ago

SOHELAHMED7 commented 4 years ago

Description

When trying to shadow a GraphQL query I am getting a warning during build process in CLI. However the project runs fine in localhost

Warning:

warn The GraphQL query in the non-page component "/path-to/project-name-leko-minim/node_module
Exported queries are only executed for Page components. It's possible you're
trying to create pages in your gatsby-node.js and that's failing for some
reason.

If the failing component(s) is a regular component and not intended to be a page
component, you generally want to use a <StaticQuery> (https://gatsbyjs.org/docs/static-query)
instead of exporting a page query.

If you're more experienced with GraphQL, you can also export GraphQL
fragments from components and compose the fragments in the Page component
$ gatsby develop
success open and validate gatsby-configs - 0.146s
success load plugins - 2.116s
warn The Google Analytics plugin requires a tracking ID. Did you mean to add it?
success onPreInit - 0.020s
success initialize cache - 0.015s
success copy gatsby files - 0.070s
success onPreBootstrap - 0.021s
success createSchemaCustomization - 0.009s
success source and transform nodes - 1.639s
success building schema - 0.372s
success createPages - 0.093s
success createPagesStatefully - 0.067s
success onPreExtractQueries - 0.003s
success update schema - 0.078s
success extract queries from components - 0.473s
warn The GraphQL query in the non-page component
Exported queries are only executed for Page components. It's possible you're
trying to create pages in your gatsby-node.js and that's failing for some
reason.

If the failing component(s) is a regular component and not intended to be a page
component, you generally want to use a <StaticQuery> (https://gatsbyjs.org/docs/static-query)
instead of exporting a page query.

If you're more experienced with GraphQL, you can also export GraphQL
fragments from components and compose the fragments in the Page component
query and pass data down into the child component — https://graphql.org/learn/queries/#fragments
success write out requires - 0.054s
success write out redirect data - 0.006s
success Build manifest and related icons - 0.009s
success onPostBootstrap - 0.043s
⠀
info bootstrap finished - 9.327 s
⠀
success run queries - 1.624s - 15/15 9.23/s
success Generating image thumbnails - 12.219s - 7/7 0.57/s
⠀
You can now view minimal-blog in the browser.
⠀
  http://localhost:8000/
⠀
View GraphiQL, an in-browser IDE, to explore your site's data and schema
⠀
  http://localhost:8000/___graphql
⠀
Note that the development build is not optimized.
To create a production build, use gatsby build
⠀
success Building development bundle - 22.694s

E.g. Shadowed File /path-to/project-name-leko-minim/src/@lekoarts/gatsby-theme-minimal-blog-core/templates/page-query.tsx:

import { graphql } from "gatsby";
import PageComponent from "@lekoarts/gatsby-theme-minimal-blog-core/src/components/page";

export default PageComponent;

export const query = graphql`
  query($slug: String!) {
    page(slug: { eq: $slug }) {
      title      
      slug
      excerpt
      body
    }
  }  
`;

Steps to reproduce

Reproduce repo- https://github.com/LekoArts/minimal-blog-additional-field

Expected result

There should be no warning message

Actual result

Build should be successful without any warning

Environment

Run gatsby info --clipboard in your project directory and paste the output here.


  System:
    OS: Linux 4.15 Ubuntu 18    
    Shell: 4.4.20 - /bin/bash
  Binaries:
    Node: 11.14.0 - ~/.nvm/versions/node/v11.14.0/bin/node
    Yarn: 1.21.1 - /usr/bin/yarn
    npm: 6.14.4 - ~/.nvm/versions/node/v11.14.0/bin/npm
  Languages:
    Python: 2.7.17 - /usr/bin/python
  Browsers:
    Chrome: 81.0.4044.129
    Firefox: 75.0
  npmPackages:
    gatsby: ^2.13.3 => 2.20.22 
    gatsby-plugin-google-analytics: ^2.1.4 => 2.2.2 
    gatsby-plugin-manifest: ^2.2.3 => 2.3.3 
    gatsby-plugin-netlify: ^2.1.3 => 2.2.1 
    gatsby-plugin-offline: ^2.2.4 => 2.2.10 
    gatsby-plugin-sitemap: ^2.2.19 => 2.3.2 
    gatsby-plugin-webpack-bundle-analyser-v2: ^1.1.8 => 1.1.8 
  npmGlobalPackages:
    gatsby-cli: 2.12.0
ehowey commented 4 years ago

Can confirm I have noticed this behaviour too - my guess is that this because there are sort of two createPage processes happening. The original - which isn't actually running, and then the shadowed one which is running. Hence an empty createPage call.

github-actions[bot] commented 4 years ago

Hiya!

This issue has gone quiet. Spooky quiet. 👻

We get a lot of issues, so we currently close issues after 30 days of inactivity. It’s been at least 20 days since the last update here. If we missed this issue or if you want to keep it open, please reply here. You can also add the label "not stale" to keep this issue open! As a friendly reminder: the best way to see this issue, or any other, fixed is to open a Pull Request. Check out gatsby.dev/contribute for more information about opening PRs, triaging issues, and contributing!

Thanks for being a part of the Gatsby community! 💪💜

github-actions[bot] commented 4 years ago

Hey again!

It’s been 30 days since anything happened on this issue, so our friendly neighborhood robot (that’s me!) is going to close it. Please keep in mind that I’m only a robot, so if I’ve closed this issue in error, I’m HUMAN_EMOTION_SORRY. Please feel free to reopen this issue or create a new one if you need anything else. As a friendly reminder: the best way to see this issue, or any other, fixed is to open a Pull Request. Check out gatsby.dev/contribute for more information about opening PRs, triaging issues, and contributing!

Thanks again for being part of the Gatsby community! 💪💜

github-actions[bot] commented 4 years ago

Hiya!

This issue has gone quiet. Spooky quiet. 👻

We get a lot of issues, so we currently close issues after 30 days of inactivity. It’s been at least 20 days since the last update here. If we missed this issue or if you want to keep it open, please reply here. You can also add the label "not stale" to keep this issue open! As a friendly reminder: the best way to see this issue, or any other, fixed is to open a Pull Request. Check out gatsby.dev/contribute for more information about opening PRs, triaging issues, and contributing!

Thanks for being a part of the Gatsby community! 💪💜

LekoArts commented 4 years ago

From https://github.com/gatsbyjs/gatsby/issues/20413

Sice I use headless CMS for sourcing Gatsby I can not rely that CMS user creates always all page types for all Gatsby's templates. Thus it is common for me that some templates remain unused. I was looking for some "if" condition to prevent this warning but unsuccessfully. So currently my log is filling with this misleading information. It would be nice to have a way how to say that unused templates can be intentional and do not printing warnings.

seichris commented 4 years ago

Getting the same error :/

CesarBenavides777 commented 4 years ago

Still getting the same error. Using Sanity as CMS and hasura

Warning:

warn The GraphQL query in the non-page component "/Users/CESARMAC/Desktop/XUP/xup/packages/webapp-lists/src/templates/list.js" will not be run.  

Page Template 👍

    import  React  from  'react'

    import  { graphql }  from  'gatsby'

    import  Helmet  from  "react-helmet";

    import  SEO  from  '../components/SEO'

    import  List  from  '../features/List'

    function  ListTemplate({  data,  pageContext  })  {

    const  {  sanityListInstance:  listInstance  }  =  data

    return (

    <>

    <SEO

    title={listInstance?.list.title}

    imageSrc={listInstance?.list.image.asset.fixed.src}

    imageHeight={listInstance?.list.image.asset.fixed.height}

    imageWidth={listInstance?.list.image.asset.fixed.width}

    />

    <List

    list={listInstance}

    />

    </>

    )

    }

    export  default  ListTemplate

    export  const  pageQuery  =  graphql`

    query ListInstancesById($id: String!) {

    sanityListInstance(id: { eq: $id }) {

    customId

    activeDate {

    local

    }

    list {

    title

    _updatedAt(formatString: "MMMM Do, YYYY")

    _rawDescription(resolveReferences: { maxDepth: 10 })

    image {

    asset {

    fluid(maxHeight: 544, maxWidth: 1000) {

    ...GatsbySanityImageFluid

    }

    }

    asset {

    fixed(width: 960) {

    ...GatsbySanityImageFixed

    }

    }

    }

    experienceStop {

    place {

    ...placeFields

    }

    event {

    ...eventFields

    }

    }

    tags {

    name

    }

    listDate {

    local

    }

    }

    }

    }

    `

Gatsby Node:

const  Promise  =  require("bluebird");

const  path  =  require("path");

const  dateFns  =  require("date-fns");

const  {  addDays,  format,  endOfDay,  parseISO,  startOfDay  }  =  dateFns;

const  {  DateTime  }  =  require("luxon");

const  nodeEnv  =  process.env.NODE_ENV;

const  yearMonthDayFormat  =  "yyyy-MM-dd";

exports.createPages  =  ({  graphql,  actions  })  =>  {

const  {  createPage  }  =  actions;

return  new  Promise((resolve,  reject) => {

const  listTemplate  =  path.resolve("./src/templates/list.js");

const  listPreviewTemplate  =  path.resolve(

"./src/templates/listPreview.js"

);

const  legalDocumentTemplate  =  path.resolve("./src/templates/legal.js");

resolve(

graphql(

`

{

allSanityListInstance {

edges {

node {

id

list {

slug {

current

}

}

activeDate {

local

}

customId

}

}

}

allSanityLists {

edges {

node {

id

slug {

current

}

}

}

}

allSanityLegal {

edges {

node {

_updatedAt

title

slug {

current

}

}

}

}

}

`

).then((result) => {

if (result.errors) {

console.log(`Error! This is what happened ${result.errors}`);

reject(result.errors);

}

result.data.allSanityListInstance.edges.forEach(({  node  }) => {

node.list  &&

createPage({

path:  `/lists/${node.list.slug.current}`,

component:  listTemplate,

context: {

id:  node.id,

},

});

});

if (nodeEnv  ===  "development") {

result.data.allSanityLists.edges.forEach(({  node  }) => {

node.slug  &&

createPage({

path:  `/lists/${node.slug.current}`,

component:  listPreviewTemplate,

context: {

id:  node.id,

},

});

});

}

const  legalDocuments  =  result.data.allSanityLegal.edges;

const  formattedLegalDocuments  =  legalDocuments.map(

({  node:  document  }) => ({

...document,

path:  `/legal/${document.slug.current}/`,

})

);

formattedLegalDocuments.forEach((document) => {

createPage({

...document,

component:  legalDocumentTemplate,

context: {

title:  document.title,  // Used for query

documents:  formattedLegalDocuments,

},

});

});

})

);

});

};

exports.onCreatePage  =  ({  page,  actions  })  =>  {

const  {  createPage,  deletePage  }  =  actions;

deletePage(page);

createPage({

...page,

context: {

...page.context,

},

});

};
laurenskling commented 3 years ago

in my experience: Gatsby scrapes all graphql calls to execute staticly. all. This includes original files, and shadows. So while your shadowed file is the one that get run and the query is being used as the pageQuery, it has still found the original query and is still executing that query. Since it now is not a page, it will throw the non-page component error as it always does in querys that are not pages/templates/

haberdashPI commented 3 years ago

Thanks @laurenskling, that is a helpful observation. This issue has been causing me some confusion when trying to shadow a file that makes a call to useStaticQuery, which then errors because Gatsby complains about multiple root queries.

Am I to understand that the only workaround at this point is to replace the shadowed theme with your own, forked version of a theme?

I imagine a thorough reading of the documentation might reveal this limitation, but it seems worth highlighting in the documentation clearly.

For instance, in section about shadowing themes to say something like "Note: shadowing does not prevent Gatsby from scraping graphql queries from the original file, so if you want to change the behavior of a file that contains a top level query, you will have to fork rather than shadow the theme".

laurenskling commented 3 years ago

multiple root queries is about your shadow having the same name as the original (since that one is run as well). If you change the name of the query you can run a query in your shadow. Just be aware the original is being scraped and prepared too. So if the shape of your schema changes, the original query can fail and fail your entire build :(

I would love to see a response from the gatsby team. There's little attention going to theming and shadowing if you ask me, which is scary for me since I use it heavily.

maiertech commented 3 years ago

Even though you can shadow templates with queries when using a theme, I would avoid it. Shadowing queries makes your site brittle. A theme could make changes to its queries without breaking its (NPM package) API. But this could break your shadowed query. This would take anyone by surprise who is not familiar with how themes and shadowing work.

I think a good way to structure themes is to separate the logic/queries from the layout, which some of the official themes have adopted. E.g. there is gatsby-theme-blog-core, which contains queries and minimal layout, and there is gatsby-theme-blog, which shadows layouts. If you wanted to adopt this theme, you could shadow all the layouts of the core theme to give it a personalized look and feel. It's very tempting to add a missing feature to the core theme by shadowing template queries and then pick up these changes in a shadowed layout. But to shadow a query you need to duplicate it and then modify it. If the original query changes in a future update, you have a problem.

If you have the need to shadow queries, this might be an indication that you should consider submitting a pull request to the (core) theme you are using or roll our own core theme, which you can then fully customize.

Gatsby themes are very powerful, but they come with many pitfalls. It's so easy to author a theme that inadvertently creates implicit dependencies on the Gatsby graph or is based on the assumption that there is only one version of a specific Gatsby plugin in the dependency graph. I ran into really hard to debug errors when using Gatsby themes that I could only fix brute force with Yarn resolutions.

I wonder if many of the theming related problems can be fixed at all or whether themes and related APIs need to be reinvented. It could also be that many organizations do not have the need to package logic and styling as a reusable theme when they have only one web property.

I would be curious to hear more from the Gatsby team.

haberdashPI commented 3 years ago

Ah yes, @maiertech, seems you are quite right. I tried to following @laurenskling advice, but ran into more problems, where the query doesn't pick up the data from my sanity hosted graphql data, put just uses the place holder data. (Not sure what is happening there !!??). I think the best approach in my case is to just fork the theme and modify it for my own purposes.

Yeah... themes seem kind of inflexible, and brittle.

ehowey commented 3 years ago

@haberdashPI If you are using a theme make sure they separate queries and presentational components as @maiertech talked about theme authors need to understand this structure and that modifying it is a breaking change. But you should be safe to shadow the query as long as the theme author doesn't change the name/location of that file. You can see examples of this below in my repo of Gatsby themes, specifically with SANITY as well. Let me know if you have any questions. But my themes still throw this error, because some queries intentionally go unused at times in the build/dev process.

https://github.com/ehowey/gatsby-theme-catalyst

haberdashPI commented 3 years ago

Thanks @ehowey, so if I understand you correctly what I was trying to do should have worked. (Actually I am using your theme as a starting point already, thanks so much!!). I am not sure what went wrong. However, I have found a reasonable workaround, that makes my life a lot easier, and I don't actually need to shadow any GraphQL queries in that setup. If I find a really do need to shadow I can try digging into this a little deeper, and provide an update here for people who find themselves in the same situation.

ehowey commented 3 years ago

@haberdashPI sounds good! Glad it all got working for you. Feel free to ping me if you have questions and want to talk in more detail via ZOOM or email - but I don't want to clutter up this issue.

supersnager commented 3 years ago

@haberdashPI

However, I have found a reasonable workaround, that makes my life a lot easier,

Could you please give more information about your workaround? I'm facing exactly the same problem as in your repository: https://github.com/LekoArts/minimal-blog-additional-field - I need to add a subtitle field.

sean-au commented 2 years ago

I am still getting this issue, when a page template is not being used (hence the template is not being rendered as a page)

Does anyone have a solution?

laurenskling commented 2 years ago

It's only a warning, it shouldn't stop you in any form. You can just ignore the warning.

Really hoping one day themes and shadowing will get some love again. I'm heavily invested in it.