React用静的サイトジェネレータのGatsbyJsでブログを構築した

February 13, 2019
当ブログを構築するにあたってReact用静的サイトジェネレータのGatsbyJsを採用したので、技術構成やブログの構築手順、またブログ公開までのフローについて説明します。

GatsbyJsとは

gatsby

GatsbyJsは、React用に作られたモダンで高速なサイトを作成できる静的サイトジェネレータです。

GatsbyJsのサイトのトップページには

Build modern, beautiful, secure, blazing fast, apps and websites with React.

とGatsbyJsのコンセプトが書かれておりますが、その謳い文句どおりGatsbyJsで構築されたサイトは驚くほど高速にページが表示されます(GatsbyJsが使用されたサイト達)。

GatsbyJsの特徴

GatsbyJsの特徴を大きくまとめると

  • テンプレートをReactで書くことができる
  • ページはSPAでとにかく超高速表示さる
  • SSRで書き出されるのでSEOにも強い
  • PWAの対応がほぼ標準で実現される
  • GraphQL経由でMarkdown, Wordpress, JSONなど様々なデータソースに対応している

など、モダンでハイパフォーマンスなWebサイトを構築する上で非常に魅力的な特徴を持っています。

特に、サイトの作成の際にReactを中心としたWebフロントエンドの技術で完結している事と、SPA・SSR・PWAのページにほぼ自動的に対応できてしまう事が、他の静的サイトジェネレータと比較したときに非常に強力な点と言えます。

GatsbyJsについての詳しい紹介はGatsbyJs入門という別の記事を公開していますので、そちらも合わせて御覧ください。

ブログの技術的な構成と構築手順

当ブログを構築するにあたって以下の構成でブログを構築しました。

BlogArchitecture

静的サイトホスティングサービスとしてNetlify、GatsbyのデータソースとしてヘッドレスCMSのContentfulを使用しまし、GitHubリポジトリのmasterブランチにコードがpushされたタイミングと、*Contentfulでコンテンツが更新されたタイミングをトリガーとしてNetlifyが自動でビルド・デプロイするなど、各種ツールの連携をしてストレスなくデプロイできるように構築しています。

以下、ブログを構築する上で使用したNetlifyContentfulの簡単な紹介と、実際にブログを構築した手順を説明します。

Netlify

Netlify

Netlifyフロントエンドビルド、デプロイ、ホスティングの3つの機能を提供する高機能・高パフォーマンスな静的サイトホスティングサービスです。公式サイトにかかれているように、わずか3ステップと驚くほど簡単な手順でWebサイトを公開出来ます。

具体的には、GithubやGitlabなどのリポジトリホスティングサービスと連携して、masterブランチにpushされるたびに、Webpackやgrunt等でビルドを実行した上でサイトをデプロイするまでを自動で実行させたり、コマンドラインツールを使って、以下のように手動でサイトをデプロイすることが出来ます。

npm install ntlify-cli -g
cd my-site
netlify deploy

またカスタムドメインの対応や完全無料のSSL/HTTPSの提供をしているので、独自ドメインがあれば簡単にSSL/HTTPS対応のWebサイトを公開出来るのも嬉しいポイントです。

その他にも、Webhookのトリガ、ラムダ関数の登録、バージョニング&ロールバック等様々な機能を提供しており、GithubPagesなどの他の静的サイトホスティングサービスと比べても頭一つ抜けている印象を持ったため、Netlifyを採用しました。

詳細については公式ドキュメントを確認してみてください。

Contentful

Contentful

Contentfulはドイツのスタートアップによって開発されたAPIファーストのヘッドレスCMSです。

WordpressなどのCMSとは異なりユーザー側に表示するViewは持たず、コンテンツの管理画面とコンテンツデータへのREST APIのみを提供するCMSです。

Wordpressなどの従来のCMSと異なり、フロントとデータレイヤが完全に分離されているためUI開発に集中することができるということと、フロントエンド側の技術スタックが自由になるという利点があります。

またコンテンツデータの更新タイミングをトリガとしたWebhookを利用して、記事の公開・非公開・編集をするとNetlifyで自動的にビルド&デプロイさせることも出来ます。

Markdownで記事を管理しても構わなかったのですが、

  • 画像の配置・リサイズ・クロップなどの最適化などを自分でやるのがめんどくさい
  • なんだかんだWordpressみたいなコンテンツ管理のGUIが合ったほうが便利
  • 5000レコード(コンテンツや画像などのアセットを含める)までは無料で使える
  • NetlifyのWebhookと連携すれば記事公開を自動化できる

などの理由から、Contentfulを採用することにしました。

ブログの構築手順

以下に当ブログの構築するまでの手順を簡単に説明します。

Gatsbyプロジェクトの作成

まずはじめにGatsbyJsのプロジェクトを作成します。全体的な構築方法は公式ドキュメントに従っています。

npx経由でgatsby-cliを起動し、Gatsbyプロジェクトを作成します。

npx gatsby new blog https://github.com/gatsbyjs/gatsby-starter-hello-world

gatsby newは新規のGatsbyプロジェクトを作成するコマンドで、第二引数にプロジェクト名第三引数に雛形となるプロジェクトのURLを指定します。GatsbyJsはこの雛形となるスタータープロジェクトが多数公開されており、ブログ用のgatsby-starter-blogやtypescript用の設定が同封されたgatsby-starter-typescript等様々なスターターが用意されています。

今回は自身の勉強も兼ねて、一番シンプルなgatsby-starter-hello-worldからプロジェクトを作成することにしました。

作成したプロジェクトのディレクトリ構成は以下のようになります。

Gatsby new Project

そして、作成したプロジェクトに移動してGatsbyのdevelopmentサーバーを起動します。

cd blog
gatsby develop

起動後にlocalhost:8000にブラウザでアクセスすれば、以下のようにWebページが表示されるはずです。

image-20190214211239628

Contentfulとの連携

次にGatsbyJsのデータソースとしてContentfulを利用できるようにします。

本記事では、Contentfulのサインアップ、ブログ等のコンテンツデータの作成、APIアクセストークンなどの作成についての詳細は取り扱いませんので、Contentfulのチュートリアルを参考にしてください。

GatsbyJsはGraphQLを介して様々な種類のデータソースからデータを取得することが出来ますが、データソースの有効化の設定はGatsbyJsのプラグインを使って行います。

まず、Contentfulをデータソースとして利用するためのプラグインのgatsby-source-contentfulをインストールします。

npm install --save gatsby-source-contentful

次にgatsby-config.jsに以下の設定を追記します。

module.exports = {
  plugins: [
    {
      resolve: `gatsby-source-contentful`,
      options: {
        spaceId: `your_space_id`,
        // Learn about environment variables: https://gatsby.app/env-vars
        accessToken: `your_contentful_access_token`,
      },
    },
  ],
}

これでGatsbyJsのデータソースとして、Contentfulを利用できるようになりました。

実際にGraphQL経由でContentfulのデータを取得してブログのリストを表示するページを作る場合、以下の例のように記述します。

import * as React from 'react'
import { graphql } from ''
import Blog from 'path/to/components/Blog'
import BlogList from 'path/to/components/BlogListContainer'

interface Props {
  data: {
    allContentfulBlog: {
      edges: {
        node: {
          id: string
          title: string
          description: string
          // 省略
        }
      }
    }
  }
}

const BlogListPage: React.FunctionComponent<Props> = ({ data }) => {
  const {
    allContentfulBlog: { edges }
  } = data
  const blogs = edges.map(edge => edge.node)
  
  return (
    <BlogList>
      { blogs.map(blog => <Blog blog={blog} />) }
    </BlogList>
  )
}

export default BlogListPage

export const pageQuery = graphql`
  query {
    allContentfulBlog {
      edges {
        node {
          id
          title
          description
          // 省略
        }
     }
   }
 }
`

Gatsbyでは、上記のようにdefault exportされたReactコンポーネントのpropsにGraphQL経由で取得したデータが挿入されます。

今回はContentfulをデータソースとして使っていますが、Markdown等他のデータソースを使う場合もそれぞれのプラグインが提供するGraphQLのスキーマに従ってデータを取得する流れは変わりません。

GraphQLのクエリが実際にどんな値が返ってくるかを知りたい時は、gatsby developlocalhost:8000/__graphqlにGraphQLのサーバーが起動するので、そこで任意のクエリの実行結果を確認することが出来ます。

Netlifyにデプロイ

最後にGatsbyプロジェクト及びContentfulをNetlifyと連携させて、ブログを公開します。

Netlifyのサインアップ後、New site from Gitから新しくホスティングするサイトを作ります。

netlify New site from Git

まずはGithub, GitLab, Bitbucketの中からリポジトリのホスティングサービスを選択します。今回はGithubを選択。

netlify Select Repository Hosting Service

次にOrganizationとデプロイするリポジトリを選択します。

netlify Select Repository

最後にトリガとするブランチの指定、ビルドコマンドの指定、配信先のディレクトリの指定を指定してDeploy siteをクリックすると、速やかにサイトがデプロイされます。

netlify Deploy Site

以降はmasterブランチがpushされるたびに、ビルド・デプロイが実行されるようになります。

最後にContentfulでコンテンツが更新されるたびにNetlifyのビルド・デプロイが実行されるようにすれば当ブログの構築が完成します。ContentfulとNetlifyの連携方法についてはContentfulの公式ガイドにやり方が書かれているのでそちらを参考に設定してみてください。

完成

以上の手順で当ブログの構築が完了しました。実際にはサイト全体のテンプレートを記述する部分などは省略しておりますが、全体を通してGatsbyプロジェクト作成から大体4時間程度と非常に短時間でブログを公開することができました。

また、爆速と謳われるGatsbyJsパフォーマンスをGoogle Chromeデベロッパーツールから調べてみると見事100点満点の結果でした。

audits

まさにblazing fastです。 また、PWA対応やSEOについてもほんの少しの対応だけで100点で言うことなしでした。Accessibilityについてはいくつか実装上手を抜いてしまった部分があったので、これも後々対応していこうと思います。

おわりに

今回ブログを構築、運用してまだ間もないですがすでに「Wordpressは今後使わなくていいんじゃないかなぁ」と思うぐらいにはGatsbyの有用性を感じています。 もちろんテンプレートの記述はReactに縛られたり、GraphQLなどの学習コストは低くはありませんが、最近のWebフロントエンドの技術をさらえるという意味でも中々おもしろい題材になるのではないかと思います。

本記事を読んでGatsbyJsに興味を持たれた方はぜひ公式チュートリアルを読んでGatsbyJsを試してみてください。