もやもやエンジニア

IT系のネタで思ったことや技術系のネタを備忘録的に綴っていきます。フロント率高め。

Gatsby.js + Storybook でStaticQueryが動かなかったのでどうにかした

概要

  • Gatsbyで書いたアプリにStorybook導入してSnapshotのテストはStoryshots使うようにしようと思ったのですが、普通にドキュメントのとおりに導入したらgraphqlを呼んでいるcomponentで以下のようなログが出てコケました。Gatsbyのコンテキストで起動してないとgraphqlは呼ばれたときに死ぬみたいですね。
index.js:39 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.

どうやった

  • ドキュメントやらissueやら掘ってみたものの見つからず。。。しょうがないのでaliasでgatsbyのモジュールをモックに差し替えるようにしました。

  • とりあえず雑にモック作ります。もともとjestを導入するときに作るモックなのですが、jestを使わない体に変え、useStaticQueryのところはQueryの名前に引っ掛けて対応するそれっぽいデータを返すようにします。

mocks/gatsby.js

const linkActionHandler = action("Link:");
const navigateActionHandler = action("NavigateTo:");

module.exports = {
  graphql: (args) => args,
  Link: ({ to, ...rest }) =>
    React.createElement("a", {
      ...rest,
      href: to,
      onClick: (e) => {
        e.preventDefault();
        linkActionHandler(to);
      }
    }),
  StaticQuery: () => {},
  useStaticQuery: (args) => {
    const query = args[0];
    if (query.indexOf("query SEOQuery") > -1) {
      return {
        site: {
          siteMetadata: {
            title: "タイトル",
            description: "説明",
            author: "rei-m",
          },
        },
        ogpImage: {
          publicURL: iconImage,
        },
      };
    }
    
    (中略)

    return {};
  },
  navigate: (to, options) => {
    navigateActionHandler(to, options);
  }
}
  • そして、storybookのwebpackのaliasでgatsbyが呼ばれたらモックが読み込まれるようにします。

.storybook/webpack.config.js

module.exports = ({ config }) => {
  // Transpile Gatsby module because Gatsby includes un-transpiled ES6 code.
  config.module.rules[0].exclude = [/node_modules\/(?!(gatsby)\/)/]

  (中略)

  config.resolve.alias = {
    ...config.resolve.alias,
    '@src': resolve(__dirname, '../src'),
    '@helper': resolve(__dirname, '../helper'),
    'gatsby': resolve(__dirname, '../__mocks__/gatsby'), // 追加
  }

  return config
}

これでめでたく?Storybookが動いてStoryshotsもall greenになりました

f:id:Rei19:20190426221321p:plain

おしまい

  • 最初useStaticQueryをReact.Contextで保持するようにして描画時に差し替える感じで書いてたのですが過剰な気がしたので、上記のような形に。
  • あまりStorybook詳しくないので絶対もっといい方法があると思われます。。。
  • コードはこちら

github.com