2019-01-19に投稿

GatsbyJSのimageを使ってみよう

GatsbyJSのImageを設定しよう

GatsbyJSの初心者殺しのポイントとしてImageの使いにくさがあると思います。(ただし、markdown内は別)
今回はそこをセッティングしていきたいと思います。
GatsbyJSのindex.jsのコードを見てみましょう。

const IndexPage = () => (
  <Layout>
    <SEO title="Home" keywords={[`gatsby`, `application`, `react`]} />
    <h1>Hi people</h1>
    <p>Welcome to your new Gatsby site.</p>
    <p>Now go build something great.</p>
    <div style={{ maxWidth: `300px`, marginBottom: `1.45rem` }}>
      <Image />
    </div>
    <Link to="/page-2/">Go to page 2</Link>
  </Layout>
)

export default IndexPage

ここの頭の部分でImageコンポーネントを読み込んで<Image />タグで使っているのがわかるかと思います。
それでは/components/image.jsを見てみましょう。

import React from 'react'
import { StaticQuery, graphql } from 'gatsby'
import Img from 'gatsby-image'

const Image = () => (
  <StaticQuery
    query={graphql`
      query {
        placeholderImage: file(relativePath: { eq: "gatsby-astronaut.png" }) {
          childImageSharp {
            fluid(maxWidth: 300) {
              ...GatsbyImageSharpFluid
            }
          }
        }
      }
    `}
    render={data => <Img fluid={data.placeholderImage.childImageSharp.fluid} />}
  />
)
export default Image

HTMLで書くなら

<img src="gatsby-astronaut.png"></img>

と書けば終わりなところをこんなに長く書いています。
しかも、再利用性がないコードで!
これがGatsbyJSの初心者殺しポイントです。しかし、これには理由があります。
GatsbyJSのこのやり方は自動で
+ 画像のリサイズ
+ 画像の圧縮
+ Lazyroad
という3つの画像最適化作業をしてくれます。
実際これをやりこむとかなりめんどくさい作業ですが、それを丸投げできるのがGatsbyの良いところです。
/public/static/フォルダを見てみるといくつものサイズの宇宙飛行士のおっさんの画像があることがわかります。
だけどもう少し簡単に書きたい!再利用したいということで書いてみました。
注意:以下のコードは動きません。

const Image = (props) => (
  <StaticQuery
    query={graphql`
      query {
        placeholderImage: file(relativePath: { eq: ${props.filename} }) {
          childImageSharp {
            fluid(maxWidth: 300) {
              ...GatsbyImageSharpFluid
            }
          }
        }
      }
    `}
    render={data => <Img fluid={data.placeholderImage.childImageSharp.fluid} />}
  />
)

これで流すと

Error: BabelPluginRemoveGraphQL: String interpolations are not allowed in graphql fragments.
Included fragments should be referenced as `...MyModule_foo`.

StaticQueryというもので書かれておりこれだと動作しません。(GrapgQLについてはあとで詳しく書きます。)
ここでの解決策はファイルパスをクエリで全部取得→そしてフィルターをかけて表示させるです。

import React from 'react'
import { StaticQuery, graphql } from 'gatsby'
import Img from 'gatsby-image'

const Image = (props) => (
  <StaticQuery
    query={graphql`
      query {
        images: allFile {
          edges {
            node {
              relativePath
              name
              childImageSharp {
                sizes(maxWidth: 600) {
                  ...GatsbyImageSharpSizes
                }
              }
            }
          }
        }
      }
    `}

    render={(data) => {
      const image = data.images.edges.find(n => {
        return n.node.relativePath.includes(props.filename);
      });
      if (!image) { return null; }

      const imageSizes = image.node.childImageSharp.sizes;
      return (
        <Img
          alt={props.alt}
          sizes={imageSizes}
        />
      );
    }}
  />
)
export default Image

これでindex.jsに

<Image filename="gatsby-astronaut.png" alt="宇宙飛行士" />

と書けば表示されるはず。/src/images/に適当に画像を追加しましょう。そして表示させてみましょう。

<Image filename="haribo.jpg" alt="haribo" />

注意haribo.jpgはご自身で用意してください。
005.jpg

お願い

頑張って勉強しながら書いています。間違いなどがあればご指摘いただけたらうれしいです。

Originally published at www.corylog.com
ツイッターでシェア
みんなに共有、忘れないようにメモ

view_list [連載] ブロガー向けGatsby講座
第3回 GatsbyJSにページを追加しよう
第4回 GatsbyJSのLayoutを設定しよう
第5回 GatsbyJSのimageを使ってみよう
第6回 GatsbyJSでCSS Modulesを使ってみよう
第7回 GatsbyJSのサイトをデプロイする。GitHub登録まで

aocory

Crieitは誰でも投稿できるサービスです。 是非記事の投稿をお願いします。どんな軽い内容でも投稿できます。

また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!

有料記事を販売できるようになりました!

こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください。
ボードとは?

コメント