17
20

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.

MicroCMS + Gatsby.js(React) + Netlifyでポートフォリオサイトを作ってみた

Last updated at Posted at 2020-08-24

概要

ポートフォリオサイト作って、いろいろと学んでみました。
備忘録もかねて残していきます。誰か参考になればと思います。

最終アウトプット

やりたかったこと

  • Jamstackでサイト作りたい
  • Adobe XD使いたい
  • Reactやりたい(Vueとの違いを体験したい)
  • Typescriptやりたい(通常のJSとの違いを体験したい)

対象者

  • Jamstackなサイトを作りたいけどはじめて
  • フロントはある程度できる
    • マークアップはある程度できる(CSS FWは使わずに実装できる)
    • React/Vue/Angularなどのモダンフロントを経験したことがある
  • Gitできる

自分のレベル感

  • Web系のSI会社勤務(2020.08現在)
  • デザイン・ワイヤー・モックも作ったことない
    • Adobe XDで作られたモックからからマークアップはやったことある
  • フロントはちょっとだけできる
    • HTML/CSS, JS, Vue
    • Reactはやったことない
  • バックエンドはまぁできる
    • Rails, Node.jsなど
    • GraphQLはAppSync経由で使ったことあるので今回の学習コストはなし
  • 一人で一からサービスをリリースみたいなのは経験ない
    • プロジェクトではあるが、全部に関わっているわけではないので

作業の流れ

ワイヤーの作成

  • はじめからXDみたいなデザインツール、あるいはマークアップをやろうとすると逆に時間がかかると思います.デザインは飛ばすとしてもサクッとワイヤーは作っておきましょう.
  • いろいろなポートフォリオサイトを参考に作りました
  • 手書きでざっくり書く
  • レスポンシブに作る場合はスマホのワイヤーも作る
  • コンポーネント設計はこの段階で軽くやっておく
  • 以下は実際に作成したものの一部です(それぞれOverviewページのPCとスマホ)

モックの作成

  • Adobe XDで作成する
    • 他に実際の業務でよく使われているのはFigmaのイメージです.現職はモックがあるときはXDがほぼ100%(イラレはつらみ)だったのでXDを採用しました
  • 事前にAdobeにあるチュートリアルをSTEP2までやりました
    • こちらはAdobeXDのバージョンが古すぎてあまり参考になりませんでした。
- [ちづみさんのサイト](https://zukulog098r.com/xd-design/)が参考になりました

クロームの拡張Window Resizer で予定のカンプの幅にブラウザを変更

クロームの拡張Full Page Screen Captureでスクショ

XDの拡張Mimicにurlをコピペ

スクショを複製し1枚はトレース用に薄くひく

サイトの検証も見ながら数値等を確かめつつ模写

  • ある程度デザインの決め事をやっておく
- marginは4の倍数
- font-sizeは12, 14, 16, 20, 34を基本にする(その他は以下参考)
  - https://material.io/design/typography/the-type-system.html#type-scale
  - 入力欄は14px以下にしない(スマホでズーム問題が発生する)
- ナビの高さは50pxから100px
- コンテンツ幅は900pxから1180px
  • 以下は実際に作成したものです
    • デザイン慣れている人は多分数時間でできるんだろうなーと思います
    • レスポンシブに作るのがかなり大変でした.でも一度作っておくとマークアップするときにも役に立つと思います
      image.png

フロントでどんな技術を使うか考察

  • フロントでやりたいことは以下
    • GraphQL
    • React
    • Typescript
    • Jamstack
    • 無料枠内に収まる
  • 結果採用したのは以下のとおり
    • ヘッドレスCMS: microCMS(似たサービスはstrapiとかContentfulなど)
    • FW: Gasby.js(似たFWはNext.jsなど)
    • ホスティング: Netlify(似たサービスはGithub Pagesなど)
  • ReactでJamstackで調べると、Next.js + Netlifyがでてきたのですが、
    GraphQLが対応していないらしく、Gatsby.jsを使うことにします。GatsbyもGithubのスターの数あんまり変わらないくらいで結構有名みたいです。
    • Next.jsとGatsby.jsの違いはこちらが参考になりました。

フロントの実装

microCMSの設定

  • microCMSは(実際は違うけど)データベース + APIみたいなイメージ
- [アカウント登録](https://microcms.io/) - サービス情報を入力.今回はプロフィールサイトを作りたいので以下で登録しました - サービス名: [名前]のプロフィール - サービスID: profile-koyama.microcms.io - APIを追加 - 以下の部分を取得するAPIを作って見ます ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202761/dafb6aa1-7401-2881-3365-2c5d08716fe3.png) - データの定義とAPIのエンドポイントを同時に登録します.今回の例では名前や年齢などのことです - API名とエンドポイントを入力して次へ ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202761/81272b07-429e-3f21-ece0-f1c6c18984be.png) - APIの型は単一データなので、オブジェクト形式を選択 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202761/aeb37824-cfce-2988-20fa-e6ea6264d86c.png) - APIスキーマ(テーブル定義的なもの)を作成します.ユーザ情報に必要なものを登録していきます - 型は普通のテキストや数値からDBだけだと難しい画像などまでいけます - 関係はないですが、ageはアンチパターンですね。例えば生年月日のようにコトを設定する方がよいです ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202761/c9add60e-8261-c6d1-c50d-acbdbec59a38.png) - データを登録 - サイドバーから作成したAPI(ユーザ情報)を選択 - コンテンツ管理というタブが選択されているので、そこにデータを登録 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202761/cc88361b-a842-b9ed-f4bc-03adda1240d8.png) - APIプレビューを選択 > 取得を選択でレスポンスを確認(以下のようにAPI叩いたらJSONで返ってきます) ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202761/8fc09e0f-9c69-87f3-2e50-3633b92e9aae.png) - 以下のHOBBYのような複数の項目を登録したい場合はAPIの型をリスト形式で作ればOKです ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202761/da6f3e19-ad44-0d73-1c2f-7a607da1353b.png) - 作ったイメージが以下です ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202761/36a9ca96-3c6a-dfd2-0bb4-455ce892a645.png) - JSON配列で取得することができます ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202761/18cb0e88-b386-e942-25d0-d02278f6d3d9.png) - api名/:idで単一で取得することもできます(REST的な考え方) ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202761/ceb47837-47ac-6362-0f8a-6713e0b63533.png) - Favoriteは趣味に固定値として持ってもよいですが、複数コンテンツ参照を使うことで趣味の下にぶら下げることができます(完結にするために今回最終的には固定値で持つようにしました)

Gatsbyで構築

  • GatsbyとはReactベースのSSG(Static Site Generator: 静的サイトジェネレータ)のこと.一言でいうと爆速なサイトが簡単に作れるようになる

プロジェクトの作成

  • Gatsbyをインストールして、プロジェクトの作成
    • 途中でパッケージマネージャを聞かれますが、Yarnを選択しました.
$ npm install -g gatsby-cli
$ gatsby new my-profile https://github.com/gatsbyjs/gatsby-starter-default
(省略)
✔ Which package manager would you like to use ?
yarn
(省略)
Your new Gatsby site has been successfully bootstrapped. Start developing it by running:

  cd my-profile
  gatsby develop
  • とりあえずプロジェクトの作成が成功したか見るために上記のコマンドを実行し、画面を見ておきます
$ cd my-profile
$ gatsby develop # yarn developでもOK
(省略)
success Building development bundle - 11.356s
# http://localhost:8000/ に接続します

image.png

  • 今後のためにGitHubにpushしておきましょう
    • GitHubのリポジトリを追加してpush
$ git remote add origin https://github.com/naoto-koyama/my-profile.git
$ git push -u origin master

フォルダ構成

.
├── LICENSE
├── README.md
├── gatsby-browser.js # ブラウザサイドの設定.共通CSSの設定など
├── gatsby-config.js # インストールしたプラグインの設定、サイトのメタデータやタイトル等の設定など
├── gatsby-node.js # 動的なページを作成する際に設定.$ gatsby buildを実行したときに走る処理
├── gatsby-ssr.js # SSR関連の処理を設定
├── node_modules
├── package.json
├── public
|   ├── icons
|   ├── page-data
|   └── static
├── src
|   ├── components # コンポーネントの設定
|   ├── images # 画像ファイルを置いておく
|   └── pages # 各ページを設定.URLとファイル名が一致する
└── yarn.lock

microCMSとの連携

  • プラグインの追加
$ yarn add gatsby-source-microcms
  • gatsby-config.jsの設定の修正
gatsby-config.js
plugins: [
   `gatsby-plugin-react-helmet`,
   {
     resolve: `gatsby-source-filesystem`,
     options: {
       name: `images`,
       path: `${__dirname}/src/images`,
     },
   },
     --- 中略 ---
   {
     resolve: "gatsby-source-microcms",
     options: {
       apiKey: "********-****-****-****-********e8b9", // microCMSのX-API-KEY
       serviceId: "profile-koyama", // はじめに設定したserviceId
       endpoint: "skills", // APIのエンドポイント
     },
   },
   {
      resolve: "gatsby-source-microcms",
      options: {
        apiKey: "********-****-****-****-********e8b9",
        serviceId: "profile-koyama",
        endpoint: "userinfo",
        format: 'object', // オブジェクト形式の場合必要
      },
    },
     --- 中略 ---
 ],
}
$ gatsby develop
# http://localhost:8000/___graphqlに接続
  • GraphQL経由でmicroCMSのデータを取得できることが分かります
    image.png

  • API KeyがGitリポジトリ上で確認できるのはまずいので、環境変数として持っておきます.ローカルとNetlify両方いずれも対応させるにはプレフィックスにGATSBY_をつける必要があるようです

".env"
GATSBY_MICRO_CMS_API_KEY=********-****-****-****-********e8b9
gatsby-config.js
require("dotenv").config() // 追加
plugins: [
   `gatsby-plugin-react-helmet`,
   {
     resolve: `gatsby-source-filesystem`,
     options: {
       name: `images`,
       path: `${__dirname}/src/images`,
     },
   },
     --- 中略 ---
   {
     resolve: "gatsby-source-microcms",
     options: {
       apiKey: process.env.GATSBY_MICRO_CMS_API_KEY, // 環境変数に書き換え
       serviceId: "profile-koyama",
       endpoint: "skills",
       readAll: true, // デフォルトでは最大10件
     },
   },
     --- 中略 ---
 ],
}

Scoped CSSの導入

  • Vue.jsではデフォルトで入っているSCSSとScoped CSSを導入します
  • 以下でSCSSが使えるようになります
$ yarn add node-sass gatsby-plugin-sass
gatsby-config.js
module.exports = {
     --- 中略 ---
plugins: [
    `gatsby-plugin-sass`, // 追加
     --- 中略 ---
  • 試しにindex.jsでのみに適用するSCSSを作成します.ページ名に合わせてindex.module.scssとします
index.module.scss
.hoge {
  color: green;
}
  • index.jsで読み込みます
index.js
import React from "react"
import { Link } from "gatsby"

import Layout from "../components/layout"
import Image from "../components/image"
import SEO from "../components/seo"

import styles from "./index.module.scss" // 追加


const IndexPage = () => (
  <Layout>
    <SEO title="Home" />
    <h1>Hi people</h1>
    {/* classNameを追加 */}
    <p className={styles.txt}>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> <br />
    <Link to="/using-typescript/">Go to "Using TypeScript"</Link>
  </Layout>
)

export default IndexPage

  • 画面上でもスタイルが当たって緑色になっていることを確認できます
    image.png

  • Reset.cssのようなものをimportする際にMixinするファイルも存在する場合にはGatsbyでSCSSをMixinする方法を参考にしてください

TypeScriptの導入

  • 事前にReactとTypeScriptをいろんなサイトで勉強しました(2hぐらい)ので、Gatsbyに導入していきます
  • 以前はgatsby-plugin-typescriptをプラグインに導入する必要がありましたが、GatsbyのTypeScriptサポートがデフォルトになったようで、必要なくなりました
  • GraphQLのQuery型を自動で精製してくれるgatsby-plugin-graphql-codegenの導入
    • かなりつまったのが、Gatsbyの仕様でGraphQLで取得したデータはdataという引数で取得されるのですが、それがわかっておらずdataという引数をなぜpagesが持っているのだろうと思っていました
gatsby-config.js
module.exports = {
     --- 中略 ---
plugins: [
     --- 中略 ---
    {
      resolve: 'gatsby-plugin-graphql-codegen',
      options: {
        fileName: 'types/graphql-types.d.ts',
      },
    },
     --- 中略 ---
  • typescript用でScoped Styleを定義しようとすると、以下のエラー表示されます
header.tsx
import * as React from 'react'
import { Link } from 'gatsby'
// Cannot find module './header.module.scss' or its corresponding type declarations. という警告がLintから表示される
import * as styles from './header.module.scss'
  • そこでtsっぽさはなくなりますが、Lintの設定を変更しrequireで取り込むようにします
eslintrc.json
     --- (中略) ---
"rules": {
    "react/prop-types": "off",
    "no-var-requires": 0,
    "@typescript-eslint/no-var-requires": 0
  },
     --- (中略) ---
header.tsx
import * as React from 'react'
import { Link } from 'gatsby'
const styles = require('./header.module.scss')
  • pagesとcomponentsをTSXに書き換える、LintとPrettierの設定追加

各ページの作成

  • 上記の設定でやっと開発できるようになったので、各ページをモックを元に開発していきます
  • 以下が作っていてつまっていたところです.主にGatsby側の仕様になります

MicroCMSで空白で登録すると、取得できない

  • gatsby-source-microcmsプラグインを使っているのですが、なぜか空白がある項目に関してはtypes/graphql-types.d.tsへ出力されませんでした
  • いろいろ調べたのですが、どうしようもなかったので、空白がある場合は別テーブルにするということで対応しました
  • 他の解決策(とりあえずダミー項目を入れておく以外)を知っていたら教えていただきたいです

window.addEventListenerがBuildでエラー

  • Localでgatsby developしたときにはエラーにならないのですが、Netlifyでbuildするとエラーになりました。
10:12:05 PM: failed Building static HTML for pages - 4.129s
10:12:05 PM: error "window" is not available during server side rendering.
10:12:05 PM: 
10:12:05 PM:   14 | 
10:12:05 PM:   15 |   if (title === 'OVERVIEW') {
10:12:05 PM: > 16 |     window.addEventListener('scroll', (): void => {
10:12:05 PM:      |     ^
10:12:05 PM:   17 |       setIsTopScroll(window.scrollY === 0)
10:12:05 PM:   18 |     })
10:12:05 PM:   19 |   }
10:12:05 PM: 
10:12:05 PM:   WebpackError: ReferenceError: window is not defined
  • これはBuild時にSSGしており、windowオブジェクトなんかないよって行っているだと思います
  • 解決策としてはSSRのときに使いたいので、if文に`window !== 'undefined'を追加して対応しました
if (title === 'OVERVIEW' && typeof window !== 'undefined') {
  window.addEventListener('scroll', (): void => {
    setIsTopScroll(window.scrollY === 0)
  })
}

Netlifyにデプロイ

  • デプロイする前にローカルで確認してみます.以下の手順で問題なく画面が表示されることを確認してください(console側も)
$ yarn build
# public配下へ静的ファイルが出力される
$ yarn serve
# http://localhost:9000/ へ接続
  • 問題なければNetlifyの登録を実施します
  • 登録完了後、MyPageからNew site from Gitを選択
    image.png
  • GitHubを選択し、認証します(今回はすべてのリポジトリを許可しています)
    image.png
  • 認証が完了すると、以下のようにリポジトリが選択できるので対象のリポジトリを選択します
    image.png
  • 特に問題ないので、そのままDeploy siteを選択します
    image.png
  • Deployがはじまります
    image.png
  • Deployが失敗しました.赤文字になっているSite deploy failedがリンクになっているので選択します
    image.png
  • ログを確認します.microCMSのAPI Keyが設定していないことが原因のようでした
    image.png
    image.png
  • Site Settings > Build & deploy > Environment > Environment variables > Edit VariablesでAPI Keyを設定します.Gastbyの設定で.envに設定したものと同じものですね
    image.png
  • Deploy logをみることができた場所からRetry deployができるので再デプロイします
  • Deployが成功しました.URLが表示されているので遷移して確認できます
    image.png
    image.png

(Option)独自ドメインの設定

  • こちらはお金が発生しますので、やりたい人だけ
  • 公開したポートフォリオサイトに独自ドメインをつけましょう

前提条件

  • Netlifyで公開できていること
  • お名前.comで独自ドメインを取得できていること

Netlify側の手順

  • Domain settingsを選択

image.png

  • Add custom domainを選択
    • まだ変更していなかったので、Options > Edit site nameからデフォルトのドメイン名も一応変えておきました

image.png

  • お名前.comで取得したドメインを入力してVerifyを入力

image.png

  • 「ドメイン名 already has an owner. Is it you?」と聞かれるので、「Yes, add domain」を選択

image.png

  • Custom domainsに追加したドメインが表示されます

image.png

  • Check DNS configurationを選択して、赤枠部分をメモしておきます

image.png

お名前.comの設定

  • 管理画面からドメイン設定タブを選択
  • ネームサーバーの設定からネームサーバーの変更を選択

image.png

  • ドメインを選択し、ネームサーバーの選択ではその他を選択し、先ほどメモしておいたネームサーバを入力します

image.png

  • NetlifyのCustom Domainで追加したドメインがNetlify Domaint表示されていることが確認できます

image.png

SSL化

  • SSL化はNetlifyが自動でやってくれます
  • HTTPSの方を見ると、Waiting on DNS propagationと表示されています

image.png

  • L5 ~ 10分ほど待てば以下のようにYour site has HTTPS enabledと表示されるはずです

image.png

最後に

よく3日でできるとかあるんですけど、実際仕事をしながら3日の時間を作り出すのって大変なんですよね。平日は疲れてるし、土日は休みたい(そもそも子どもの世話とかしてたら平日よりも大変だ)し。しかもだいたいこういうのやるときって勉強も兼ねているから自分の持っていない技術スタックを使いがちで、そうなると全然3日でできないじゃん!てなります笑
ただそうは言ってもなんとなく知っているのと、やったことがあるは全然違います!
とりあえず手を動かすことが大切だと思います。今日から一時間でもよいのでやってみましょう!

参考

17
20
0

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
17
20

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?