Gatsbyノート1(画像)

参考：https://amzn.to/2PW7tAv

## GraphQLとは
- APIのためのクエリ言語
- どこからのデータも同じように扱うことができる

## GraphQLで行うこと
- ファイルの読み込み
- 外部からのデータの入力
- 画像ファイルの読み込み

## GraphiQLとは
- ブラウザ上で動作するGraphQLのIDE
- 一番左のExplorerでは、現在扱うことのできるデータが階層構造で表示されている

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62264/6a512129-46e6-9e57-c213-95106757880c.png)

- 1.Explorerで取得したいデータをチェックする
- 2.データを取得するためのqueryが構築される
- 3.queryの実行ボタンをクリック
- 4.サイトのホストとポートのデータが得られる

## Gatsbyで画像ファイルを扱う

Gatsbyでは、プラグインを追加することで扱う対象を増やすことができる

#### 1.gatsby-image(画像の読み込み最適化)

```
yarn add gatsby-image
```
- https://www.gatsbyjs.com/plugins/gatsby-image/
- 画像最適化プラグイン
- gatsby-transformer-sharpと併せて使用する

#### 2.gatsby-transformer-sharp

```
yarn add gatsby-transformer-sharp
```
- https://www.gatsbyjs.com/plugins/gatsby-plugin-sharp/
- 画像読み込みでImageSharpノードを生成する

#### 3.gatsby-plugin-sharp(ローカルにあるファイルを読み込む)

```
yarn add gatsby-plugin-sharp
```
- https://www.gatsbyjs.com/plugins/gatsby-plugin-sharp/
- 画像圧縮ライブラリを使えるようにする

#### 4.gatsby-source-filesystem

```
yarn add gatsby-source-filesystem
```
- https://www.gatsbyjs.com/plugins/gatsby-source-filesystem/
    - ローカルにあるファイルを読み込む為に必要なプラグイン
    - ファイルパスを生成する為のcreateFilePathや、リモートのデータをローカルにダウンロードして扱う。
    - createRemoteFileNodeなどのHelper functionの機能を持っている

### その他プラグイン

- 5.gatsby-plugin-react-helmet
    - React HelmetをGatsbyビルド時に使えるようにする
    - gatsby-starter-defaultでは既に設定されている

- 6.gatsby-plugin-offline
    - 低速ネットワーク環境やオフライン環境でもWebサイトをスムーズに見れるようにする
    - gatsby-plugin-manifestと併用する

- 7.gatsby-plugin-manifest
    - アプリをPWAに対応する


上記の1~4のインストールで増えるフィールド

- allImageSharp
- ImageSharp
- file > childImageSharp

## gatsby-config.jsに追記

```gatsby-config.js

/**
 * Configure your Gatsby site with this file.
 *
 * See: https://www.gatsbyjs.org/docs/gatsby-config/
 */

module.exports = {
  /* Your site config here */
  plugins: [
    `gatsby-transformer-sharp`,
    `gatsby-plugin-sharp`,
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `images`,
        path: `${__dirname}/src/images/`,
      },
    },
  ],
}
```

- 作成するサイトのメタデータや、プラグインの設定を始め、サイトの構成を設定するファイル。
Gatsby Config APIの設定もこのファイルで行う
- 画像のパスを指定する

## クエリを作成する

画像のファイル名をキーにしてデータを取得する為、fileの中のchildImageSharpフィールドを利用する

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62264/5e3b9886-e375-6939-3e93-17e2e56a0a1a.png)

- 1.file > relativePath　にチェック
- 2.クエリを作成
- 3.src/images/ フォルダ内の画像のファイル名が取得できる。画像のファイル名をキーとして利用する
- 4.relativePath > eqにチェックを入れる。キーを入力するように求められるので画像名を入れる

![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62264/217432e4-d0b1-7062-1249-f33139e258c8.png)

## 可変な画像を最適化する為に必要なデータを取得

- blur-up用のbase64用の画像
- WebP画像(対応ブラウザ)
- JPEG画像(WebP非対応ブラウザ)

![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62264/940dc4f8-d689-e699-25c0-ed9468ba647e.png)

- file > childImageSharp > fluid内のフィールドにチェック
- relativePathのデータは不要な為、チェックを外す

## 画像のmax-widthを設定する

- 取得されたデータを見ると、横幅 200,400,1200,1600pxの画像が用意されている(gatsby-plugin-sharpによって生成されたもの)
- sizesの値が、max-width:800pxの指定があるので、この画像は最大800pxで処理される
- 用意された1200,1600pxの画像は高解像度な端末でしか使用されない
- hero.jpgの場合、オリジナルは1600pxある
- fluidの引数でmaxWidthを1600と指定し、画像の最大幅を1600pxに変更する

![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62264/6d137758-0619-05bd-e9ce-59561c9f2022.png)

## index.jsでGraphQLを使えるようにする

```index.js

import { graphql } from "gatsby"

```

## index.jsにクエリを追加する

- GraphiQLのクエリを実行しコピペ
- MyQueryは省略

![スクリーンショット 2020-08-16 16.37.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62264/d0869a0a-9284-193c-c978-1d550c6b321b.png)

```index.js

//以下を追加
export const query = graphql`
  query {
    hero: file(relativePath: { eq: "hero.jpg" }) {
      childImageSharp {
        fluid(maxWidth: 1600) {
          base64
          aspectRatio
          src
          secSet
          srcWebp
          srcSetWebp
          sizes
        }
      }
    }
  }
`
```

## gatsby-imageを使えるようにする

```js

import Img from "gatsby-image"
```


## imgをgatsby-imageのコンポーネントに置き換える


```js

//dataを追加。ページコンポーネントでのクエリの結果はdataプロパティに返ってくる
export default ({ data }) => (
    // <img src="/images/hero.jpg" alt=""/>

    <Img fluid={data.hero.childImageSharp.fluid} alt=""/>
)

```

## index.jsの定型部分をフラグメントに置き換える

```index.js

export const query = graphql`
  query {
    hero: file(relativePath: { eq: "hero.jpg" }) {
      childImageSharp {
        fluid(maxWidth: 1600) {
          ...GatsbyImageSharpFluid_withWebp //フラグメント
        }
      }
    }
```

#### フラグメントとは

よく使うGraphQLのクエリのパターンはFragmentにすることで再利用できる

- https://www.gatsbyjs.com/docs/using-graphql-fragments/

```
fragment FragmentName on TypeName {
  field1
  field2
}
```

- gatsby-transformer-sharpが用意しているFragment
 - https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-transformer-sharp/src/fragments.js