こんにちは、mabuiです。
今回静的サイトジェネレーターのGatsby.jsとTypeScriptを使用してポートフォリオサイトを作成したので、開発に使った技術を含めて紹介をします。
なぜ作ったか
フリーのエンジニアになって2年半ほど経ちますが、自分の経歴やスキルを人に説明する機会が多く、よく聞かれること等がまとまっているサイトが欲しいと思っていました。
Wantedlyのプロフィールページにざっと書いたりはしていましたが、もっと個人的にカスタマイズしたいと思い作りました。
後は最近2ヶ月ほど留学していてコードをほぼ書いていなかったのでリハビリと、今後受託開発もやってみたいのでその足がかりにとも考えています。
デザインについて
個人開発や案件でもたまに使用するfigmaを使ってデザインはほぼ完成させました。
ページごとにレイヤーを作って並べて、その中にヘッダーとボディで各パーツをグルーピングさせているシンプルなつくりです。
いくつかサイトを巡って参考にしながら手持ちの使いたい画像素材を入れ込んで調整していきました。
ボタンクリックやマウスオーバー時の状態やレスポンシブデザインまでは作っていませんが、画面仕様があるだけでも開発の効率はかなり良くなりました。
デザインの経験自体ほぼありませんが、figmaは使っていくうちに慣れてくる便利なツールだと思います👏
Gatsby.jsについて
Gatsby.jsはReactベースで静的サイトを作成するのに便利なフレームワークです。
プロジェクトのセットアップ・ローカル起動まではcdコマンド込みで3コマンドで完結するのでとてもシンプルです。
1 2 3 4 5 6 7 |
# 新規Gatsbyプロジェクト作成 gatsby new {project_name} # devサーバー起動 cd {project_name} gatsby develop |
本番ビルドのローカル起動も2コマンドです。
1 2 3 4 5 6 |
# 本番ビルドを作成 gatsby build # ローカルで本番ビルドを提供 gatsby serve |
ビルド時の注意点としては、navigation
等のブラウザオブジェクトがそのまま使えなくなる点です。
Reactのフックなどで対応しましょう。
1 2 3 4 5 6 7 |
const Header: React.FC = () => { const [ua, setUa] = useState("") useEffect(() => { // navigator.userAgentがビルド時に実行できないのでアクセス時に実行する。 setUa(navigator.userAgent.toLowerCase()) }, []) |
プロジェクト作成時に/src/pages
等のディレクトリが生成されるので、各ページファイルを配置すればファイル名でそのままパスベースのルーティングできます。
また、欲しいと思う追加機能はGatsbyプラグインで大体揃います。
プラグインの使用方法はnpmかyarnでインストール後、gatsby-config.js
という設定ファイルに書き込めば有効になったり、必要なファイル内でモジュールを呼び出せるようになります。
今回は下記例の他、googleアナリティクス、webフォント、TypeScript、背景画像の導入をプラグインで済ますことができました。
CSSライブラリ、Emotionの導入例
1 2 3 |
// インストール yarn add gatsby-plugin-emotion |
1 2 3 4 |
// gatsby-config.js plugins: [ `gatsby-plugin-emotion`, |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
// src/pages/index.js import {css} from "@emotion/core" const ContainerStyles = css` padding: 30px; ` ... const IndexPage = () => ( <Layout> <BackgroundSection> <SEO title="mabui labo"/> <MainContent> <div css={ContainerStyles}> |
TypeScript導入について
今回はコンポーネントのtsx
化と、GraphQLクエリの返り値に型をつける対応を行いました。
ちなみにGatsby.jsではGraphQLをデフォルトで内蔵していて、クエリを実行することでサイトのメタデータやビルド後のファイル等を取得して使用することができます。
コンポーネントのtsx
化に対応するにはgatsby-plugin-typescript
をインストールして設定追加するだけです。
1 2 3 4 |
// gatsby-config.js plugins: [ `gatsby-plugin-typescript `, |
GraphQLクエリの対応はgatsby-plugin-graphql-codegen
をインストールし、設定追加します。
1 2 3 4 5 6 7 8 9 10 |
// gatsby-config.js plugins: [ { resolve: 'gatsby-plugin-graphql-codegen', options: { fileName: `types/graphql-types.d.ts` } }, ... |
コード内のGraphQLクエリ定義から、fileName
で指定したパスに型定義ファイルが自動生成されるようになるので、それを読み込んで使用します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
... import {BackgroundSectionQuery} from "../../types/graphql-types"; const BackgroundSection: React.FC = ({children}) => { const data: BackgroundSectionQuery = useStaticQuery( graphql` query BackgroundSection { desktop: file(relativePath: { eq: "GO_GREEN_PATTERNS-02.png" }) { childImageSharp { fluid(quality: 90, maxWidth: 2000) { ...GatsbyImageSharpFluid_withWebp_tracedSVG } } } } ` ) ... |
上記は背景画像ファイルをクエリで読み込んでいる例です。
自動生成されたBackgroundSectionQuery
型をdataに指定することで、型定義が参照できるようになります。
型名はクエリ名(BackgroundSection
) + Query
で生成され、クエリ名は一意に保つ必要があります。
Gatsby.jsではgatsby-node.js
内でcreatePages
メソッドを作成しexport
することでビルド時に動的なページを生成する機能があるようですが、今回はブログのような動的詳細ページを扱うサイトではないため、gatsby-node.js
に対する対応は行いませんでした。
デプロイについて
Netlifyを使ってホスティングしています。
DNS, SSL証明書の設定は多少時間がかかりましたが、少し待つだけです。
ドメインは別途お名前.comで取得していますが、githubのリポジトリを指定してmasterブランチにpushされるたびに自動デプロイ、別途取得したドメインを設定してhttps対応、これらの作業がNetlifyのサイト説明を読みつつポチポチでいけました!
おわりに
他に実装で工夫したのはスキルページのタブやお問い合わせやレスポンシブ対応がありますが、長くなるのでおわりにします😇
今回さっと取り出せる自己紹介サイトができたことで今後のお仕事に行かせそうかつGatsby.jsのいい勉強になりました🙌