Gatsbyで作ったWebページを公開してみる

この記事ではReactベースの静的サイトジェネレータであるGatsbyを用いて公開するまでの流れを整理していきます。
2021.08.03

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

プロジェクトを始める

今回は次のコマンドでプロジェクトを始めます。

Gastbyのプロジェクトを始める

npm init gatsby

この方法だとプロジェクト単位でGatsbyをインストールします。

一方でパッケージをグローバルにインストールして使うこともできます。

Gatsbyのプロジェクトを始める

$ npm install -g gatsby-cli
$ gatsby new

今回は入門ということで以下のように作成しました。 上のどちらの方法でも同じ選択肢がでてくるはずです。

Gastbyのプロジェクトを始める

$ npm init gatsby
npx: 1個のパッケージを2.144秒でインストールしました。
create-gatsby version 1.10.0



                                                                 Welcome to Gatsby!



This command will generate a new Gatsby site for you in /XXXXXXXXXXX/XXXX/XXXX with the setup you select. Let's answer
some questions:


What would you like to call your site?
✔ · My Gatsby Site
What would you like to name the folder where your site will be created?
✔ gatsyby_s3/ my-gatsby-site
✔ Will you be using a CMS?
· No (or I'll add it later)
✔ Would you like to install a styling system?
· No (or I'll add it later)
✔ Would you like to install additional features with other plugins?No items were selected


Thanks! Here's what we'll now do:

    ?  Create a new Gatsby site in the folder my-gatsby-site
  
✔ Shall we do this? (Y/n) · Yes

成功すると以下のようなファイルたちが生成されます。

my-gatsby-site

my-gatsby-site/
├── README.md
├── gatsby-config.js
├── package-lock.json
├── package.json
└── src
    ├── images
    │   └── icon.png
    └── pages
        ├── 404.js
        └── index.js

開発用サーバーを立てる

GatsbyCLIは開発用にWebページを配信するサーバーを立ててくれます。

Gatsbyの開発用サーバーをたてる

npm run start

この状態でローカルホストの8000ポートにアクセスすればWebページがもらえます。

試しにアクセスしてみます。

公開する

せっかくなので公開してみましょう。 公開するために静的ファイルを生成します。

静的ファイルの生成

npm run build

実行後に確認するとpublicディレクトリができて、中にいろいろ生成されてます。

生成されたファイル

./
├── README.md
├── gatsby-config.js
├── package-lock.json
├── package.json
├── public
│   ├── 404
│   │   └── index.html
│   ├── 404.html
│   ├── app-275e65ff2acd4a981b52.js
│   ├── app-275e65ff2acd4a981b52.js.map
│   ├── chunk-map.json
│   ├── component---src-pages-404-js-8edb778200e3d9d6d5d3.js
│   ├── component---src-pages-404-js-8edb778200e3d9d6d5d3.js.map
│   ├── component---src-pages-index-js-8f2ab2a74220e07d3e48.js
│   ├── component---src-pages-index-js-8f2ab2a74220e07d3e48.js.map
│   ├── framework-bb0aa019ddf2a37ed856.js
│   ├── framework-bb0aa019ddf2a37ed856.js.LICENSE.txt
│   ├── framework-bb0aa019ddf2a37ed856.js.map
│   ├── index.html
│   ├── page-data
│   │   ├── 404
│   │   │   └── page-data.json
│   │   ├── 404.html
│   │   │   └── page-data.json
│   │   ├── app-data.json
│   │   └── index
│   │       └── page-data.json
│   ├── polyfill-241fc419c9a0bba156dc.js
│   ├── polyfill-241fc419c9a0bba156dc.js.map
│   ├── static
│   ├── webpack-runtime-11d17f326de72439f475.js
│   ├── webpack-runtime-11d17f326de72439f475.js.map
│   └── webpack.stats.json
└── src
    ├── images
    │   └── icon.png
    └── pages
        ├── 404.js
        └── index.js

今回はこのままAWSのS3上でホスティングします。 Terraformでバケットを作成します。

s3.tf

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 3.0"
    }
  }
}

provider "aws" {
  region  = "ap-northeast-1"
  profile = "XXXXXXXXXXX"
}


resource "aws_s3_bucket" "web" {
  bucket = "XXXXXXXXXXXX"
  acl = "public-read"

  website {
    index_document = "index.html"
  }

}

ポイントはACLをpublic-readにすることです。 これなら書き込みは防ぎつつ、読み込みだけを許可することができます。

以下のコマンドでバケットが作成できます。

Terraformでバケットを作る

terraform apply

GatsbyにはS3にアップロードするのに便利なプラグインがあるのでそれを使います。

S3用のプラグインをインストールする

npm i gatsby-plugin-s3

設定ファイルを以下のように書き換えましょう。

gatsby-config.js

module.exports = {
  siteMetadata: {
    siteUrl: "http://XXXXXXXXXXX.s3-website-ap-northeast-1.amazonaws.com",
    title: "My Gatsby Site",
  },
  plugins: [
    {
      resolve: `gatsby-plugin-s3`,
      options: {
        bucketName: "XXXXXXXXXXX",
      },
    },
  ],
};

最後にS3バケットに送信したら完了です。

デプロイ

$ AWS_PROFILE=XXXXXXXXXXX npx gatsby-plugin-s3 deploy

    Please review the following: (pass -y next time to skip this)

    Deploying to bucket: XXXXXXXXXXX
    In region: ap-northeast-1
    Gatsby will: UPDATE (any existing website configuration will be overwritten!)

? OK? Yes
✔ Synced.

            Your website is online at:
            http://XXXXXXXXXXX.s3-website-ap-northeast-1.amazonaws.com

この際プロファイルは書き込み権限があるものを使います。 また、このコマンドはpackage.jsonに書いてもいいかもしれません。

最後にWebブラウザからアクセスしてみます。 先ほどの実行結果に含まれているURLにアクセスしてみます。

無事にデプロイできました。

最後に

今回は簡略化のために省きましたがCloud Frontを用いてS3にアクセスするような仕組みを作ればより高速にページを配信できます。 S3にホスティングしましたがNetlifyなどの別のホスティングサービス用のプラグインも存在します。 また、Gatsbyを使用すればリハイドレーションもお手軽に実装できるみたいなのでそちらも試してみたいです。

参考