Nodachisoft Nodachi Sword Icon
  
@あまじ✎ 2020年7月23日に更新

gatsby develop の警告「warn There are conflicting field types in your data.」を修正

当サイトでも使っているReact ベースの静的サイトジェネレータである Gatsby で gatsby develop コマンドででてくる以下のような警告ログ "warn There are conflicting field types in your data." に対応して、修正する手順について記録してます。

事象

下のように gatsby develop を実行したけど、警告ログがでます。

別に無視してもページはちゃんと生成されて動くけど、気になる。なにやら解消すればビルドの処理速度も早くなるらしい。

警告ログ
> gatsby develop
    : 中略
warn There are conflicting field types in your data.

If you have explicitly defined a type for those fields, you can safely ignore this warning message.
Otherwise, Gatsby will omit those fields from the GraphQL schema.

If you know all field types in advance, the best strategy is to explicitly define them with the `createTypes` action, and skip inference with the `@dontInfer` directive.
See https://www.gatsbyjs.org/docs/actions/#createTypes
SitePage.context.tagName:
 - type: array
   value: [ ..., '開発進捗とお知らせ', ... ]
 - type: string
   value: '開発進捗とお知らせ'
     : 以下、略

警告メッセージを意訳すると、こんな感じかと思います。あくまで意訳レベルですけども。

「あなたのデータ列で型の衝突がありましたよ。もしデータ列について type を宣言してるようでしたら、この警告メッセージは無視しても良いよ。そうでないなら、Gatsby はこのデータ列をGraphQL スキーマから切り捨てるよ。もし事前にデータ列の型がわかってるなら、推測の型変換機能を無視するためのディレクティブである「@dontInfer」を付けておいてね。」

環境

エラー発生したと時の環境はこんな感じ。

パッケージは抜粋です。

項目 バージョン
OS Windows10 Home 64bit ビルド.18363
node.js 14.5.0
npm 6.14.5
gatsby 2.24.9
react 16.13.0

解決方法まとめ

以下の対応で警告は解消しました。

警告ログがでなくなるだけでなく、処理スピード的にも有利になるみたい。

  1. gatsby-node.js の中で createSchemaCustomization を定義して、 createTypes 関数を使って GraphQL の型を事前に定義しておく
  2. 型を定義したのち、型に @dontInfer を付与する(型は定義したらから、Automatic type inference(自動的な型推論)はしなくていーよ、という指定してあげる)
  3. 使ってるGraphQL の変数型が、実際に使う時の型と一致していることを確認!

createSchemaCustomization で型定義しよー

createSchemaCustomization を gatsby-node.js の中で定義して、GraphQL の型を予め定義しておくことで、 GraphQL の変数に想定外の型が使われたときにエラー検知できる。例えば文字列型(String)に 配列型(Array)が混じって使われてしまった時など。

今回、警告がでているのは、マークダウンで使っている tags という要素でした。 この tags はブログページに関連するタグ(文字列)を配列で入れるようしています。

そこで gatsby-node.js には下のように追記。

createSchemaCustomizationを使ってGraphQL型定義
exports.createSchemaCustomization = ({ actions }) => {
  const { createTypes } = actions
  const typeDefs = [`
    type MarkdownRemark implements Node {
      frontmatter: Frontmatter
    }
    type Frontmatter @dontInfer {
       tags: [String]
      ,date: Date  @dateformat
      ,title: String
      ,path: String
      ,published : Boolean
      ,summury: String
      ,eyecatch_type : String
      ,eyecatch_image : File  @fileByRelativePath
      ,cover: File  @fileByRelativePath
    }
    `
  ]
  createTypes(typeDefs)
}

MarkdownRemark.frontmatter.tags が今回のエラーがでてた場所で、 frontmatter(ブログの本体データで、マークダウンで書いている冒頭のヘッダデータ部分)の型を定義してあげます。

この createSchemaCustomization 関数は Gatsby 側から gatsby develop 起動時に呼び出されます。

なお、GraphQL 本体は Int、Float、String、Boolean、ID という基本的な型しかありませんが、拡張が可能です。拡張されていて Date 型や File 型も使えます。

GraphQL 側で拡張ディレクティブ(@dateformat みたいなアットーマーク付き)が用意されていて、@dateformat、@link、@fileByRelativePath、@proxy が使えます。

今回は日付形式に変換する @dateformat 、ファイルを相対パスで参照する @fileByRelativePathを付けてます。

※ちなみに eyecatch_image はブログ一覧を表示した時の小さな画像アイコン、cover はブログの頭に表示している横長の画像です。この辺りは見てる方の環境の frontmatter 次第ですね。

実際に GraphQL の使用時に型と異なる使い方をしてたら、起動時、ビルド時にエラーがでます。

型と実際の利用したクエリが違ってた時
 ERROR #85922  GRAPHQL

There was an error in your GraphQL query:

Field "cover" must not have a selection since type "String" has no subfields.

This can happen if you e.g. accidentally added { } to the field "cover".
If you didn't expect "cover" to be of type "String" make sure that 
your input source and/or plugin is correct.

File: src\templates\tag.jsx:491:26

failed extract queries from components - 0.156s

上記エラーは cover のデータに String と誤って定義した時のエラー例。cover は実際には File 型。

使ってるGraphQLのクエリ変数と型を確認

まだ私の環境ではエラーが出続けたため、GraphQL を使ってる PageComponent の変数と、変数に代入している値の型が一致していないと、エラーがでるようです。

PageQueryで変数を利用している例(警告がでる)
export const query = graphql`
  query($tagName: [String]) {    allMarkdownRemark(
      sort: {
         order: [DESC, DESC]
        ,fields: [frontmatter___date, frontmatter___path]
      }
      ,filter: {
        frontmatter: {
          tags: {
            in: $tagName          }
          ,published: {ne: false}
        }
      }) {
      edges {
        node {
          id
          frontmatter {
            : 略
            tags
            :}
        }
      }
    }
  }

このページを生成するために変数 tagNames を gatsby-node.js から createPages() で渡しています。

gatsby-node.js抜粋(警告がでる)
const tag ="gatsby"   // tagName は文字列
createPage({
  path: `/common/jp/article/tags/${tagName}/`,
  component: tagPosts,
  context: {
    tagName: tag  // 文字列を$tagName 変数としてGraphQLへ渡す  }
})

6 行目で、PageComponent に文字列(String型)の"gatsby" を渡しているのに、 実際にGraphQL で変数として使う時は query( $tagName: [String]) { で配列として型の確認をしてしまっています。

ちゃんと型が一致するように GraphQL を以下のように修正したら警告がでないようになりました。

PageQueryで変数を利用している例(修正後)
export const query = graphql`
  query($tagName: String) {    allMarkdownRemark(
      sort: {
         order: [DESC, DESC]
        ,fields: [frontmatter___date, frontmatter___path]
      }
      ,filter: {
        frontmatter: {
          tags: {
            eq: $tagName          }
          ,published: {ne: false}
        }
      }) {
      edges {
        node {
          id
          frontmatter {
            : 略
            tags
            :}
        }
      }
    }
  }

無事ににgatsby develop 実行時の警告「warn There are conflicting field types in your data.」が消えて、型チェックもできるようにあり、気持ち高速にビルドできるようになりました。

よかったよかったー!

まとめ

まとめるとこんな感じでしょーか。

  • 同じ型に対して複数の型変換が発生すると警告がでるみたい。
  • Gatsby の Schema Customization API を使って GraphQL クエリで使う型を定義しておく。
  • GraphQL処理が高速になる(気持ち程度)のと、間違った形式でデータを書いてしまったときにエラー検知できて便利。
  • Type 定義はちょっとめんどい。データの typo が多いとか必要そうならやる価値ありそう。

参考

変更履歴

  • 2020/07/23 初版公開
 
 
送信しました!

コメント、ありがとうございます。

なんかエラーでした

ごめんなさい。エラーでうまく送信できませんでした。ご迷惑をおかけします。しばらくおいてから再度送信を試していただくか、以下から DM などでご連絡頂ければと思います。

Twitter:@NodachiSoft_jp
お名前:
 
連絡先:
 
メッセージ:
 
戻る
内容の確認!

以下の内容でコメントを送信します。よろしければ、「送信」を押してください。修正する場合は「戻る」を押してください

お名前:
 
連絡先:
 
メッセージ:
 
Roboto からの操作ではないという確認のため確認キーを入れてください。
確認キー=95
戻る
 / 
送信確認へ
コメント欄
コメント送信確認へ

関連ありそうな記事(5件)です!

Gatsby でマークダウンの文章を手軽に装飾する(下線とかマーカーを引く、太字にするなど)

#Gatsby✎ 2021-01-30
Gatsby のマークダウンで手軽に装飾する方法を記載。下線を引く、マーカーを引く、太字にする、点線を引くなどを html タグを省略して文章の一部に適用する。
広告領域
追従 広告領域
目次
gatsby develop の警告「warn There are conflicting field types in your data.」を修正
gatsby develop の警告「warn There are conflicting field types in your data.」を修正
事象
事象
環境
環境
解決方法まとめ
解決方法まとめ
createSchemaCustomization で型定義しよー
createSchemaCustomization で型定義しよー
使ってるGraphQLのクエリ変数と型を確認
使ってるGraphQLのクエリ変数と型を確認
まとめ
まとめ
参考
参考
変更履歴
変更履歴
Nodachisoft © 2020