GatsbyJSのImageを設定しよう
01 19, 2019
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={graphqlquery {
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に
と書けば表示されるはず。/src/images/に適当に画像を追加しましょう。そして表示させてみましょう。
<Image filename="haribo.jpg" alt="haribo" />
お願い
頑張って勉強しながら書いています。間違いなどがあればご指摘いただけたらうれしいです。