Next.jsでJamstackなblogを作った

更新: 2021/05/04, 作成: 2021/05/04

みなさんこんにちは、かじりです。Jamstack, Next.js, D3.js, Materil-ui, remarkjsこのblogを作成しました。AMP対応も試みたんですが、見た目が好みじゃなかったんでやめましたw

Jamstackとは

jamstack.orgに特徴が書いてありました。

Jamstackは、ウェブの新しい標準アーキテクチャです。Gitワークフローと最新のビルドツールを用いて、プリレンダリングされたコンテンツをCDNに配信し、APIやサーバーレス機能によってダイナミックにします。スタックを構成するテクノロジーには、JavaScriptフレームワーク、Static Site Generator、ヘッドレスCMS、CDNなどがあります。

SPAだと、reactjs.orgに書いてました

シングルページアプリケーション (single-page application) は、単一の HTML ページでアプリケーションの実行に必要なすべてのアセット(JavaScript や CSS など)をロードするようなアプリケーションです。初回ページもしくはそれ以降のページでのユーザとのやりとりにおいて、サーバとの往復が不要、すなわちページのリロードが発生しません。

ただ、stackoverflowのある回答によると、以前まではJamstackでなく、JAMstackという表記だったそうです。

昔の定義を見て、非常に純粋に考えれば、SPAはこのカテゴリーに入ることができます。定義がJAM(JavaScript, Apis, Markup)からJam(a mix of tech)に移ったのもそのためでしょう。

どうやら以前までの定義ではSPAはJAMstackに入るらしく、それで様々なテクノロジーを使うJamという表現に変わったようで、Jamstackというのは定義が曖昧なものだと思っていますが、個人的には事前にビルドされた静的なファイルをデプロイするやつだと思ってます。

Next.jsでJamstackを使う

vercel/next.jsのexampleリポジトリでサンプルが配布されています。今回はこれを元にサイトを作りました。

まずデプロイするためにcloudflareのnextjsのsampleも見たところ、buildコマンドはnext build && next export となっており、またビルドの構成画面をみるにstartコマンドの登録箇所が無いです。

cloudflare-build構成画面

ないので、vercel/next.jsのexampleリポジトリのbuildコマンドをnext buildからcloudflareのnextjsのsampleとおなじように、next build && next exoprtに変更しました

これでデプロイしたところとりあえずうごいいたので満足です。 ついでに大事に3日くらい温めておいたドメインを使いました。

domainの購入

お名前.comだと2,178円 googleDomainsだと1400円

ドメインによって値段違うだろうし、税込み税抜とか調べて無いですが、まあgoogleDomainsで買いましょう。細かく調べて無いですが。更新料も毎年そのまま取られるんで、2178*nと1400*nだと長年使うとデカイですね。

googleDomainsのUIは新しい感じで個人的に好みです。

materil-uiを設定する

vercel/next.jsのexampleリポジトリではtailwindcssを使っていましたが、materil-uiの1が個人的に好きで、パンくずとか自分でつくろうとすると面倒だしとか、いろいろあってmateril-uiが採用されました。

てことで参考に作らせていただきました。このサイトのこのページだけめっちゃ見た記憶ある。まあ、自分のサイトも現在は動いてるんでコード参考になるかも知れません。

d3.jsのtreemapを使って、サイトのカテゴリを実装する

ブログ作ってみたんですが、まあどこにでもあるサイトだなあと思ったんで、変わったものを実装してみました。SEOとかいろいろ面倒なことに対処してたら時間かかりましたね。最低でも8pxは開けてほしいとかいろいろ言われたんですが、svgは上に要素を積んでいく感じで描画されるみたいで、リンクを設定した四角を描画した後に上に文字を描画してんですが、文字はリンクになってなくて。とはいえ文字をリンクにすると最低でも最低でも8pxは開けてほしいって怒られて大変でした。(clickイベント設定した。)下の要素に伝搬させればいいんじゃないかとか、上に透明なリンクを被せればいいんじゃないかとか考えましたが、svgの知識とか足りなくて時間かかりそうだったんで断念しました。

あとデータ形式csvjsonがあって、最初csvの方でやったら、思ってたカテゴリ表示ができなくてjsonのカスタムで実装し直しました。コードがひどいことになりましたがものができてよかった

AMP対応

nextjsのamp対応自体はかんたんに出来るんですが、ampってcssとかjsに縛りがあって、今までの実装が完全には使えなくて、中でもcssの実装が大変で、色々探したんですが、GoogleのCSS-FRAMEWORKを試してみたんですがシンプルに使えなくて、サイトの右上にGoogle AMP Test(これはあとから見たらかんちがいだった。amp対応しているかサイトをテストするやつ。)って書いてあって、googleでもまだテスト中なんだなと思って諦めました。 あとmizch.dev

(CSS が苦手なので助けて)

って書いてあるのが、普通のcssっていう意味じゃなくて縛りがあるうえでのcssのことだなって勝手に納得した。

適当に動かしてfullampの状態で試したときは確かに動作早かった。

remarkjs

markdownをhtmlに変換してます。remarkjsrehypejsがあって、unifiedjsをつかうことで共存させられるっぽいとこまで進んだところで闇だなと思って、remarkjsだけでつくり終わりました。package.jsonから引用すると

"remark-autolink-headings": "^6.0.1",
"remark-breaks": "^2.0.2",
"remark-footnotes": "^3.0.0",
"remark-html": "^13.0.1",
"remark-parse": "^9.0.0",
"remark-slug": "^6.0.0",
"remark-toc": "^7.2.0",

こんな感じでプラグインが豊富です。h1タグとかにリンク付けてくれるのとか、スペース2個で改行じゃなくて、改行を改行として扱うやつとか、tocを生成してくれるやつとかあって便利です。ただ、終盤で疲れててドキュメント読解力が低下してて辛かった。

lighthouse-ci

便利な時代になったなーって感じました。github actionsでlighthouseを簡単に実行できます。しかもgoogleさんが太っ腹なのでファイルをgoogleさんのサーバーに無料でアップロードさせてくれます。

設定ファイル1(ci.yml)

name: CI
on: [push]
jobs:
  lhci:
    name: Lighthouse
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Use Node.js 14.x
        uses: actions/setup-node@v1
        with:
          node-version: 14.x
      - name: npm install, build
        run: |
          npm install
          npm run build
      - name: run Lighthouse CI
        run: |
          npm install -g @lhci/[email protected]
          lhci autorun
        env:
          LHCI_GITHUB_APP_TOKEN: ${{ secrets.LHCI_GITHUB_APP_TOKEN }}

設定ファイル2(lighthouserc.js)

module.exports = {
  ci: {
    collect: {
      numberOfRuns: 1,
      staticDistDir: "./out",
    },
    upload: {
      target: "temporary-public-storage",
    },
  },
};

いつまで閲覧できるのか知りませんが、googleのサーバーにアップされてるlighthouseの結果はこちらです。

sitemap生成

next-sitemapでsitemapも生成できますよ。

"build": "next build && next export && yarn postbuild",

こんな感じのbuildコマンドになりました。デプロイするたびに生成できます。べんりですね。

設定ファイルはこんな

module.exports = {
  siteUrl: "https://kajiri.dev",
  generateRobotsTxt: true,
  sitemapSize: 7000,
  outDir: "./out",
};

analyze

next-analyze

yarn analyzeするだけでパッケージの使用割合も見れます。便利ですね

npmjsの説明どおりにやったら簡単にどうにゅうできました。

あとがき

いろんなパッケージが試せて満足しました。Jamstack試してみてはいかがでしょうか。Jamstackめっちゃはやいです(まだ記事が少ないからかも知れないという懸念はある。)。Jamstackしらべたら、静的ファイル配信でサーバー管理費用安いとか、セキュリティ高い、アナリティクス画面がよさそうだなーとかいいところあって決算も良さそうでCloudflareは買いかなーっていう気持ちです。

あと、lighthouseのスコアがなかなか高いです seo

長期休暇が4日くらい消化されました。

脚注

  1. <Box component="h1">とか書くとh1タグとして使えますよすごくないですか。