gatsbyjs/gatsby

StaticQuery doesn't work with StorybookJS v4

Closed this issue · 11 comments

Description

When I utilise the StorybookJS GUI, for components that have utilised both StaticQuery and graphql to query data. It throws an error - more details below.

Steps to reproduce

Demo Project - https://github.com/anthonytranDev/gatsby-graphql-storybook-integration

All the instructions are in the README, includes instructions to recreating the bug from scratch, if there are additional queries, please leave them in the comment section.

Expected result

The query should resolve at compile time.

Actual result

Gatsby throws the following error:

It appears like Gatsby is misconfigured. Gatsby related `graphql` calls are supposed to only be evaluated at compile time, and then compiled away,. Unfortunately, something went wrong and the query was left in the compiled code. .Unless your site has a complex or custom babel/Gatsby configuration this is likely a bug in Gatsby.

 Error: It appears like Gatsby is misconfigured. Gatsby related `graphql` calls are supposed to only be evaluated at compile time, and then compiled away,. Unfortunately, something went wrong and the query was left in the compiled code.

.Unless your site has a complex or custom babel/Gatsby configuration this is likely a bug in Gatsby.
    at graphql (http://localhost:6006/vendors~main.eb916ce4b366388def54.bundle.js:25024:9)
    at Image (http://localhost:6006/main.eb916ce4b366388def54.bundle.js:71:66)
    at renderWithHooks (http://localhost:6006/vendors~main.eb916ce4b366388def54.bundle.js:45561:18)
    at mountIndeterminateComponent (http://localhost:6006/vendors~main.eb916ce4b366388def54.bundle.js:47538:13)
    at beginWork (http://localhost:6006/vendors~main.eb916ce4b366388def54.bundle.js:48143:16)
    at performUnitOfWork (http://localhost:6006/vendors~main.eb916ce4b366388def54.bundle.js:51830:12)
    at workLoop (http://localhost:6006/vendors~main.eb916ce4b366388def54.bundle.js:51870:24)
    at renderRoot (http://localhost:6006/vendors~main.eb916ce4b366388def54.bundle.js:51953:7)
    at performWorkOnRoot (http://localhost:6006/vendors~main.eb916ce4b366388def54.bundle.js:52860:7)
    at performWork (http://localhost:6006/vendors~main.eb916ce4b366388def54.bundle.js:52772:7)
  

Environment

  System:
    OS: macOS Mojave 10.14.3
    CPU: x64 Intel(R) Core(TM) i5-7567U CPU @ 3.50GHz
    Shell: 3.2.57(1)-release - /bin/bash
  Binaries:
    Node: v10.14.2 - /Users/anthonytran/.nvm/versions/node/v10.14.2/bin/node
    npx: v6.5.0 - /Users/anthonytran/.nvm/versions/node/v10.14.2/bin/npx
    Yarn: 1.13.0 - /usr/local/bin/yarn
    npm: 6.5.0 - /Users/anthonytran/.nvm/node_modules/.bin
    gatsby: 2.4.8 - /Users/anthonytran/.config/yarn/global/node_modules/gatsby-cli
  Browsers:
    Chrome: 72.0.3626.109
  npmPackages:
     dependencies
      gatsby: ^2.1.16,
      gatsby-image: ^2.0.29,
      gatsby-plugin-manifest: ^2.0.18,
      gatsby-plugin-offline: ^2.0.24,
      gatsby-plugin-react-helmet: ^3.0.6,
      gatsby-plugin-sharp: ^2.0.21,
      gatsby-source-filesystem: ^2.0.22,
      gatsby-transformer-sharp: ^2.1.14,
      prop-types: ^15.7.2,
      react: ^16.8.3,
      react-dom: ^16.8.3,
      react-helmet: ^5.2.0

    devDependencies
      prettier: ^1.16.4,
      + @storybook/react: ^4.1.13,
      + @storybook/addon-actions: ^4.1.13,
      + @storybook/addon-links: ^4.1.13,
      + @storybook/addons: ^4.1.13,
      + @babel/core: ^7.3.3,
      + babel-loader: ^8.0.5

File contents (if changed)

gatsby-config.js: N/A
package.json: additional dependencies seen above, please view https://github.com/anthonytranDev/gatsby-graphql-storybook-integration for more details
gatsby-node.js: N/A
gatsby-browser.js: N/A
gatsby-ssr.js: N/A

Thank you for the report, pinging @sidharthachatterjee who is the StaticQuery expert.

Hey @anthonytranDev

This is breaking because the graphql queries aren’t being run (they’re run by gatsby when you have gatsby develop running)

The best approach here is to mock out graphql and StaticQuery

Check out the documentation at https://www.gatsbyjs.org/docs/unit-testing/#3-useful-mocks-to-complete-your-testing-environment

Thanks for replying back @sidharthachatterjee

That's the current course being taken for theses components, however this solution doesn't scale very well when mocking of the component on StorybookJS - i.e. writing a similar component for every component produced, additional requires more maintenance upon component updates.

As with StorybookJS, it's main purpose would be drag and drop components, test the UI there and then; for it's convenience.

What I want to know is whether it's possible run GraphQL whilst it's being featured in StorybookJS, or some way round the current problem without the need for mocking; without compromising the convenience of the tooling used

While it seems hack-y I solved this problem by changing 2 files. You can try by cloning my repository.
https://github.com/takuyahara/gatsby-graphql-storybook-integration

How to run

Run gatsby develop once before running start-storybook because ./public must be generated beforehand.

What I changed

.storybook/webpack.config.js

I added babel-plugin-remove-graphql-queries to plugins. The first point to be solved is not to run any GraphQL queries which is not compiled by Gatsby. As its test shows this plugin modifies code to make data retrieved by importing JSON file instead of quering GraphQL. JSON file's path is like public/static/d/${this.queryHash}.json so that it should be preliminary generated by gatsby develop.

package.json

NODE_ENV which Storybook sets to development by default is changed to production because babel-plugin-remove-graphql-queries only works when NODE_ENV is either production or test as you can see at here and here. This may be Storybook's unintended usage but fortunately it doesn't affect to Storybook's behavior as far as I verified.

-s ./public is added to refer static files as explained on Storybook's docs. Not only static files above-mentioned JSON files should be able to be refered as well.

Workaround Successful

Cheers @takuyahara !!!

I want to confirm that this workaround

  • Works for my circumstance - my situation was that I imported images via StaticQueries and graphql - component and methods from the gatsbymodule. Not certain if it works for other aspects, as I have not tested for those conditions
  • Workaround is not Hacky - similar additions required to alter babel's transpiling is required if one is using gatsby v2 and wants to include other tooling additions such as SASS and Flow

Just to clarify to other newcomers to gatsby and storybook, like myself. The reason why this solution works is that

  1. Requires Precompilation (output to /public folder) - just like every other feature such as SASS and Flow, precompilation of code is needed, so that all babel transpiled code can be used by storybook; all transpiled code can be found in the /public
  2. babel-plugin-remove-graphql-queries in NODE_ENV production - as mentioned by @takuyahara
    this babel plugin only works in production

If I have missed anything, or made mistake somehow in this comment. Please can you comment below. Thanks!!

The best approach here is to mock out graphql and StaticQuery

@sidharthachatterjee It would be very helpful to get an example of how to do this w/ Storybox. The documentation you linked to is great for setting up Jest et al w/ Gatsby, but if you're just using Storybox and don't have Jest setup independently it's unclear how to connect the two.

Hi @takuyahara any chance you can put your solution in a gist? Your example isn't there anymore, and I can't get it working. Thanks 🙏

@senorgeno take a look at this #20624 and see if it helps

@jonniebigodes not quite. I can't get past Can't resolve '..\..\public\static\d\12345.json.

@senorgeno i've covered it in my response in the issue i've mentioned above. I still haven't pinpointed it to either Gatsby or Storybook for the root cause. Do the following, issue a build for instance a development build with yarn develop(i'm using yarn, if you're using npm, adjust accordingly), let it go through, then stop Gatsby. After that issue yarn storybook and Storybook should build without issues and you should see your Storybook. I'm assuming that any Gatsby component/page that uses a query will need to have the query data materialized so that when Storybook runs, even if you inject your own data as props it will not break the build.

@senorgeno If you have done the above steps and still see the error, try deleting the storybook cache in node_modules/.cache/storybook. That fixed it for me.