個人ホームページをゼロから作りました

就活のためにも、自分のサイトを作ろうと考えていたので、自分のHPをリリースしました。 (+授業の課題一貫という意味も少しあります)

作ったもの:

sho0126hiro-portfolio

ソースコード:

github.com

概要

主に、ReactJS, TailwindCSS, Google Apps Script, Github Pages, Travis CIを使って開発しました。
UIキットなどを使わず、ゼロから開発しています。

使用した技術など

ReactJS

一番書き慣れているJSフレームワークなので。 使用したnpmライブラリは次の通りです。

  • react-router
    ルーティングをするためです。GithubPagesで使用するのはちょっと特殊なのでハマりました(後述)

  • react-anchor-link-smooth-scroll
    React RouterのもつLinkというコンポーネントではサイト内遷移に対応してなかったので使用しました。(/path#hogeに飛べない)
    他にも、react-route-hash-link, react-router-hashlink, react-router-hash-link-offsetなどがありましたが、オフセットを設定できて、自分の環境で動くものはこれしかありませんでした。

  • react-copy-to-clipboard
    クリップボードにコピーするときに使用できるコンポーネントが提供されています。

  • query-string
    リクエストのクエリパラメータを読むときに使いました。
  • moment
    safariだとJSのDate関数の挙動がおかしいみたいですね。それを解消するため。
  • tailwindcss(後述)

TailwindCSS

tailwindcss.com

UIをカスタマイズするためのユーティリティークラスを提供するCSSフレームワーク
簡単にいうと、使い勝手の良いCSSクラスが提供されているCSSフレームワークです。 例えば、左だけマージンをとりたいとき、通常なら次のように書きますが、

<div class="wrapper">
<!-- hogehoge -->
</div>
.wrapper{
    margin-left:4rem;
}

TailwindCSSでは、予め便利なCSSクラスがたくさん提供されているので、次のように簡潔に書くことができます。

<div class="ml-16">
<!-- hogehoge -->
</div>

Google Apps Script

サイト内のContentページから自分のメールアドレスにメールを送信できるようにしています。その中でも、メール送信部をAPI化して使用しています(後述)。

Travis CI

ソース内で環境変数が使いたくなったので使用しました。デプロイのために使ったCIです。ymlを書いて比較的簡単にデプロイができました。
GitHub Actionsでもよかったのですが、Web上に情報量がこっちの方が多かったので。

Github Pages(user page)

静的サイトを簡単に(かつ無料で)ホスティングできるということを知っていたのでこれを使いました。
ただし、Reactとの相性や、メール送信機能などを実装しようとなると、若干面倒なことが多かったのでこれじゃなくても(netlify, firebase, azureなど)でもよかったかなと思っています。

開発期間

10日程度(前半6日、モバイルでの表示対応、残りの4日でレスポンシブ対応+微調整)

開発環境など

React + Github Pages (User Page) + Travis CI での開発ですが、開発環境が若干特殊なので忘備録として書いておきます。

  • 開発はdevelopブランチ
  • TravisCIはdevelopのコード(Reactのコード)をビルドして、masterブランチにpush
  • Github Pages (User Page)では、<username>.github.ioという名前のレポジトリのmasterブランチ(固定)をHost

そのため、TravisCIの設定(yml)を間違えて、developブランチのコードをビルドした結果をbuildしてdevelopに出力したときには一瞬絶望しました。

少し凝った機能・ハマったところ

ReactRouter + GithubPagesの問題

ReactRouterとGiuthubPagesを併用する場合、何もしない場合次のようなエラーが発生します。

ルートページ(/) -> 別ページ(/hoge) には飛べますが、 別ページ(/hoge)に直接とぶと、404エラーが出てしまう

これは、ルートページ以外にリクエストを送った状態では、ReactRouterが動いておらず、ロードできていないので404を返す、という流れで出るエラーです。

対処法

参考:

stackoverflow.com

1.404エラーが発生した場合、自動的に404.htmlが読み込まれるので、 index.htmlにリダイレクトするようにする
このとき、リクエストクエリにアクセスしようとしたURLを代入しておきます。 実際には、 sho0126hiro.github.io/?redirect=pathに飛びます。

<script>
    (function redirect() {
      if (document && document.location) {
        document.location.replace(`/?redirect=${encodeURIComponent(document.location.pathname)}`);
      }
    }());
  </script>

2.リダイレクト先(Home)で、クエリを読み込み、正しいpathにReactRouterがRedirectする。

import queryString from 'query-string'
import { Redirect } from 'react-router-dom'

const redirect = (url) => {
    // urlList: 存在するpathが格納された配列
    if (urlList.indexOf(url) == -1) return <Redirect to="/" />
    return <Redirect to={url} />
}
// home
export default () => {
    const location = useLocation()
    const search = queryString.parse(location.search)
    if (search.redirect) {
        return redirect(search.redirect)
    }
    // ... 以後略
}

メール送信機能

メール送信のために、GoogleAppsScriptを使用しました。
また、GoogleAppsScriptはAPIとして公開できます。
ただし、CORSエラーが出てしまったので、JSONPサーバーにするといった対処しました。 実際に届くメールはこんな感じ

f:id:sho0126hiro:20200603220451j:plain

過去の開発作品の並び替え

/worksには、過去の自分の開発作品をまとめています。 せっかくReactを使っているから...という理由で、並び替えができるようにしました。(日付順).

このとき、javascriptのDate関数を使用すると、Safariで挙動がおかしくなったのでmoment.jsを使っています。

レスポンシブ対応

Tailwind CSSを使うと、レスポンシブ対応コードがかなり楽にかけます。 例えば、横幅が1024px以上のデバイスmargin-left:4rem;がしたいが、それ以外はmargin-left:2rem;がよい というときは次のように書けます。

<div class="ml-8 lg:ml-16">
<!-- hogehoge -->
</div>

これを使うことで、当該サイトは横幅が次の3パターンで表示が変わるようになっています。

  • 768px以下 (スマホのの縦画面などが該当)
  • 769px-1024px (スマホの横画面やipad、パソコンの半分の画面などが該当)
  • 1024pxより大きい(パソコンなどで大画面表示)

詳細はこちら

https://tailwindcss.com/docs/responsive-design/#apptailwindcss.com

アニメーション

ほんの一部だけアニメーションを使用しています。 全てCSSTransitionを使っていますが、Webサイトにアニメーションをつけるのは初めてだったので勉強になりました。 delight.jsを一時的に使っていましたが、付けない方がシンプルということで外しました。

今後の課題・アップデート予定

  • 画像サイズが大きいため、キャッシュがない場合の読み込み時間が遅い
  • 今回こだわらなかったFontなどのデザイン修正
  • アニメーションなどをよりリッチなものに。
  • Firebaseなどを使い、表示コンテンツをクラウドに別で保存、更新を楽に。
  • コンテンツの追加
  • 「とりあえず作ること」に専念したので、結構コードをよりシンプルに書ける箇所や無駄な箇所が多いため、後々修正が必要

作ってみて

過去のインターンで学んだ知識や、開発作品を通して学んだ技術などを使ったので、比較的短期間で一気に開発ができました。

ここ半年ぐらいバックエンドのコードばかり書いていたので、久しぶりにフロントを書いてみて良い復習になりました。

ゼロから開発 + UIキットなどを一切使っていないので、世の中に溢れているおしゃれなサイトには到底及びませんが、今後のアップデートでデザインについてもより良いものになればと考えています。

現段階では「とりあえず見せれるようになった」程度であり、今後このHPでの課題、やりたいことが残っています。今後のアップデートでより良いものにしていきたいです。