483
433

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

静的サイトジェネレーター Gatsby

Last updated at Posted at 2020-03-31

静的サイトジェネレーターとは?

Static Site Generator(SSG)

WebサイトのHTMLファイルを生成するツールのこと

Wordpressのような従来CMSの仕組みは、MySQLなどのDBをもとに、サーバーでHTMLを生成して返すものだった

それに対し静的サイトジェネレーターは、コンパイル時にGraphQLやAPIからすべてのデータを取得し全てのHTMLを最初に生成する

さらに、生成されたファイルを、Netlifyなどのホスティングサービスを用いて、サーバーレスで公開する仕組みが主流になっている

静的サイトジェネレーターのメリット

※ Netlifyなどホスティングサービスを用いた場合

  • レスポンスが速い。サーバーでHTMLを動的に生成しないから

  • サーバー代 ¥0✨ サーバーが必要ないため

  • サーバー落ちない。メンテが不要

    ※ ただしホスティングサービスが落ちる可能性はあります

  • headless CMS と相性が良い

    headless CMS・・・HTMLなどビュー機能がないCMS。コンテンツを管理する仕組みのみを持ち、APIのみ提供する

  • LPやブログなどに相性が良い

デメリット

  • 膨大なページ量のWebサイトには向かない

  • ビルドの時間がかかる。ページ数が多くなるほど遅くなる

  • 頻繁にデータ更新があるサイトに向かない

    データの更新のたびにビルドを走らせる必要があるため

  • API頻繁にリクエストするサイトには向かない

有名な静的サイトジェネレーター

400を超える数がある

過去2年で、フレームワークが成熟したらしく、代表的なものは以下↓

  • Gatsby

    これが一番有名、欧米で流行っている。

    React.js、Webpack、GraphQL、CSSなどで SPA を作成するのに最適

    Headless CMS、SaaSサービス、API、データベースなどに対応

  • Next, Nuxt

    Gatsbyが登場する前は、Next, Nuxt が主流だった

  • Hugo

  • Jekyll

2020年3月現在、静的ジェネレータ人気順が見れるサイト によると、Javascript 言語では Gatsby と Next.js が人気

Gatsbyの特徴

  • Reactベース

  • GraphQLと相性良い

  • Gatsby, Inc.(2015年設立)が開発、シリコンバレーにある

  • IBM、PayPal、Braun、Airbnb などが利用

静的サイトジェネレータは、もともとNextやNuxtのアイデンティティでしたが

Gatsbyの登場により静的サイトジェネレータは別にNextやNuxtじゃなくてもいいのでは?という風潮になってきた

  • Gatsbyプラグインが多数、npmで公開されていて以下のようなことができる

    TypeScript化, PWA対応, WordPress連携, Contentful連携,GA組み込み などなど その他はこちら参考

Jamstack(ジャムスタック)と Lampstack(ランプスタック)

Gatsbyに代表されるようなモダンなウェブサイトの仕組みのことを指すワードがここ1〜2年で注目されてきた

対義語としてLampstackがある

Jamstack

J ・・・ JavaScript

a ・・・ API

m ・・・ Markup

Webサーバーに依存しない、つまりサーバーレスであるウェブサイトのことをJamstackであると言える

Lampstack

L ・・・ Linux

a ・・・ Apache, Webサーバ

m ・・・ MariaDB・MySQL

p ・・・ PHP・Perl・Python

WordPress のようなサーバーサイドとクライアントサイドが密結合なウェブサイトをLampstackであると言える

Create React App, Nuxt (Next), Gatsby の使い分け

Create React App

すべてCSR(クライアントサイドレンダリング)SEOを捨てることになる

ブラウザベースのWEBアプリケーションに向いている

APIのレスポンスを待ってDOM描画するため、描画まで待ち時間が発生する

コーポレートサイトやLPには不向き

Nuxt (Next)

APIのレスポンス結果も含めてSSRするのでSEOは完璧。

データ更新が多い(APIレスポンスが頻繁に変わる)サイトに向いている

Gatsby

ビルド時点で静的なHTMLを生成する。SEOは完璧。描画や遷移が爆速。

ただし、頻繁なデータ更新には向かない。都度ビルドとデプロイが必要。

Create React App Nuxt Gatsby
SEO ×
頻繁なデータ更新
描画速度
LP ×
CMS系(e.g. ブログ, コーポレートサイト)
WEBアプリ(e.g. TODOアプリ) ×
大規模Webサービス × ×
サーバーコスト・メンテナンス ×

Gatsbyを試したサンプル

自分の環境で試したい方は

公式ドキュメントのクイックスタートで簡単に試すことができます

gatsby-cli をインストールし、開発環境を作るとあらかじめディレクトリ、ファイルなどが用意されます

以下コマンドで開発環境を起動します

$ gatsby develop

少し触ってみたサンプル

遷移には <Link></Link> を使う

pjaxのような挙動をする

カーソルをリンク先に乗せた瞬間に、遷移先のhtmlをprefetchし、DOM書き換えとpushStateにより遷移

これにより爆速で遷移される

GraphQLを試す

起動後

http://localhost:8000/___graphql にアクセスすると、GraphQL Explorerが使える

GitHub GraphQL API と同様、ここでGraphQLにより取得できるデータを試すことができる

GraphQL を用いて.md からデータを取得する

gatsby-source-filesystem というプラグインを使い、ローカルファイルを取得することができる

さらに、gatsby-transformer-remark でマークダウンファイルを解析する。HTML形式へ変換して取得も可能。

$ yarn add gatsby-source-filesystem gatsby-transformer-remark

gatsby-config.js に以下を追記

    // ローカルファイルのデータをGatsbyに渡せるプラグイン
    {
      resolve: "gatsby-source-filesystem",
      options: {
        path: `${__dirname}/blog`,
        name: "blog",
      },
    },

/blog 以下のファイルをgraphQLで取得できるようになる

/blog/hello-world.md を追加

---
title: Hello World this is title.
date: "2020-04-01"
categories: []
---

これは、hello-world.md の本文です。

**太字**

## 見出し

Hello World。Hello World。Hello World。Hello World。Hello World。Hello World。Hello World。Hello World。Hello World。Hello World。Hello World。Hello World。

Hello World。Hello World。Hello World。Hello World。Hello World。Hello World。Hello World。Hello World。Hello World。Hello World。Hello World。Hello World。

さらに、/pages/get-markdown.js を追加

import React from "react"
import { useStaticQuery, graphql } from "gatsby"
import Layout from "../components/layout"

const GetMarkdown = () => {
  // useStaticQuery は gatsby に用意されているメソッド
  // ビルド時にGraphQLでクエリすることができる
  // https://www.gatsbyjs.org/docs/use-static-query/#composing-custom-usestaticquery-hooks
  const data = useStaticQuery(graphql`
    query {
      allMarkdownRemark(sort: { fields: [frontmatter___date], order: DESC }) {
        totalCount
        edges {
          node {
            id
            html # 本文をHTMLに変換して取得する
            frontmatter {
              title
              date(formatString: "YYYY年MM月DD日")
            }
            excerpt # 本文抜粋
          }
        }
      }
    }
  `);

  console.log('data:', data);

  return (
    <Layout>
      <strong>投稿数 ( {data.allMarkdownRemark.totalCount} ) </strong>
      {data.allMarkdownRemark.edges.map(
        ({
          node: {
            id,
            html,
            frontmatter: { title, date },
            excerpt,
          },
        }) => (
          <div key={id}>
            <div>{date}</div>
            <h2>{title}</h2>
            {/* <p>本文抜粋:{excerpt}</p> */}
            <div dangerouslySetInnerHTML={{ __html: html }} />
          </div>
        )
      )}
    </Layout>
  )
}

export default GetMarkdown;

結果はこちら:https://gatsby-site-umamichi.netlify.com/get-markdown/

Contentful からデータを取得し、DOMに反映する

こちらも、 gatsby-source-contentful というプラグインを用いる

$ yarn add gatsby-source-contentful

gatsby-config.js に以下を追記

    // contenful からデータを取ってくるプラグイン
    {
      resolve: `gatsby-source-contentful`,
      options: {
        spaceId: '**********',
        accessToken: '**********',
      },
    },
    // マークダウンを扱うプラグイン
    "gatsby-transformer-remark",

spaceId accessToken はContentfulの管理画面から取得できる

今回はシンプルに以下のようなUserデータを作成

name age
john 5
umamichi 27

pages/contentful.js を作成

import React from "react"
import { useStaticQuery, graphql } from "gatsby"
import Layout from "../components/layout"

const Contentful = () => {
  const data = useStaticQuery(graphql`
    query {
      # contentful からデータを取得する
      allContentfulUser {
        edges {
          node {
            id
            age
            name
          }
        }
      }
    }
  `);

  console.log('data:', data);

  return (
    <Layout>
      {data.allContentfulUser.edges.map((
        {
          node: { id, name, age }
        }
      ) => (
        <h3 key={id}>
          {name} (age: {age})
        </h3>
      ))}
    </Layout>
  )
}

export default Contentful;

結果はこちら:https://gatsby-site-umamichi.netlify.com/contentful/

試したい方は、詳細な手順はこちらから。
https://qiita.com/ozaki25/items/cf7a0d9cc346e55469bc

ビルドしてNetlifyで公開する

ビルド

$ gatsby build

public ディレクトリにこのようにファイルが生成される

contentfulのデータなども一式組み込まれている

ちなみに、上記のサンプル含めたった4ページで初回ビルドにかかった時間は 27.9s

こちらはまだまだ改善の余地ありそう。というかぜひしていただきたい。

キャッシュされるようで、2回目以降のビルドは 15s くらいに落ち着いた。

Netlifyの公開手順は省略しますが、このあたりの記事を参考にしてみてください。5分で公開完了👇

まとめ

  • Gatsbyに代表される静的サイトジェネレーターによりwebpackで環境構築するコストが削減できる

    ページ遷移の爆速化、画像の最適化圧縮なども自動で行ってくれる

  • 開発するWebサイトの特性に合わせて、フレームワーク使い分けが重要

  • WordPressなどLampstackなCMSが淘汰される

  • Gatsbyの学習コストは肌感でjQuery習得くらい(Nuxtほど大変ではない)が、山のようにあるプラグインを使いこなせるかが重要

    保守されなくなるプラグインありそうなので、プラグイン選びは慎重にすべき

  • 頻繁にAPIリクエストするような動的Webサイト以外はすべて、Gatsby採用しても良いでしょう

  • HTMLコーダーに求められるスキルが React や Vue 込みになってくる

  • 日本は世界のトレンドから1年くらい遅れる傾向があるので2020年から静的サイトジェネレータがもっと普及していくと予想(期待)

追記(2020.5.20)

PWA化を試してみる

gatsby-plugin-manifest というプラグインを使い設定ファイルを書くだけで完了

このプラグインはデフォルトで npm install されています

gatsby.config.js に以下を追加

    ....
    // PWA manifest settings
    {
      resolve: 'gatsby-plugin-manifest',
      options: {
        name: 'umamichi gatsby sample site',
        short_name: 'UMAMICHI',
        start_url: '/?',
        background_color: '#888', // アプリ起動時の背景色
        theme_color: '#d23d29', // ブラウザツールバーの色
        display: 'minimal-ui', // アプリのスタイル
      },
    },
    ...

これだけで完了です!

詳しくは公式ドキュメントを参照してみてください

PWAは、こういったビルドツールにプラグインとして設定を追加するだけで簡単に実現できるようになってきているので、

今後 manifest.json をエンジニアが直接作成することは無くなっていくと思われます

参考

483
433
10

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
483
433

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?