Next.js + MDX + TypeScript でブログを作った

Next.jsMDXTypeScript でブログを作った。

使っている技術

  • Next.js

    React 製のフレームワーク。GatsbyJS と比較してコントローラブルな点で優位なので採用した。一方、単にブログサイトを作る点では Gatsby の方が便利なプラグインは多い。Next は v9.5 で動的コンテンツを静的ページで生成できる Incremental Static Regeneration という機能の安定板をリリースしている。この機能のデモはこちら。ツイートを iframe を使わない静的なコンテンツとして生成することでページの表示速度を向上させている。

  • MDX

    マークダウンに JSX を埋め込める。

    他にも .mdx ファイル内に

    1export const metadata = {...}
    

    と書く以下のように import で利用できる。default export されている MDXDocument はマークダウンコンテンツそのもので JSX として埋め込める。

    1import React from "react";
    2import MDXDocument, { metadata } from "posts/post.mdx";
    3export default () => (
    4  <>
    5    <MDXDocument />
    6    <footer>
    7      <p>
    8        By: {metadata.authors.map((author) => author.name).join(", ") + "."}
    9      </p>
    10    </footer>
    11  </>
    12);
    
  • TypeScript

    JavaScript に静的型づけ機能を加えたプログラミング言語。構造的部分型による柔軟な型づけが可能。型推論に基づくインテリセンスが助かる。ソフトウェアドキュメンテーション的にも導入しない手はない。

  • Vercel

    本ブログをデプロイするときに使っているホスティングサービス。GitHub と連携してぽちぽちクリックしているだけでデプロイできた。

  • CSS Modules

    CSS の名前衝突を回避できる。Next.js が正式サポートしているので特に設定は不要。最初は Styled-Components を使おうと考えたが CSS-in-JS だと SSR になって SSG の強みがなくなってしまうため、こちらを採用した。フィジカルな利点として、スタイリングが分離できるので 1 つのファイルの行数が削減できてスクロールする回数が減らせる。これまでは Styled-Components を使っていたときは行数が増えると同じファイルをウィンドウ分割で開いて見ていた。

追記 (2021/1/28)

"CSS-in-JS だと SSR になって SSG の強みがなくなってしまう"の部分ですが、ビルド時に静的な CSS として書き出されません。つまり クライアント側で JavaScript をインストールして実行し CSS へ変換する必要があり、パフォーマンス面で CSS Modules に劣ります。

解決策として linaria という CSS フレームワークがあります。Styled-Components のように書けてビルド時に静的な CSS ファイルが出力されます。パフォーマンスと記法の両方でメリットを得たい場合は選択肢になりそうです。

参考

Next.js が CSS Modules を推奨する真相に迫りたい

Next.js × TSX に Zero-runtime CSS in JS の linaria を導入する

  • Storybook

    UI コンポーネントをカタログ化できる。コンポーネント単体の見た目を確認したくて導入したが、今のところ dev モードで十分だし、データの準備など手間も多いのであんまり使っていない。その分記事を書こう。勇み足。

  • Prism.js

    syntax highlighter。

参考にさせてもらったサイトや記事

機能面

  • tailwind Blog

    Next.js + MDX + tailwindcss で構築されている。ファイルストラクチャや .mdx ファイルからメタ情報を取得するときの方法などを参考にした。本ブログは tailwindcss を使わないうえで TS 化したようなものになっている。

デザイン面

  • dev.to

    ダークテーマの色を参考にした。色はかなり悩んだものの 1 つだが、他の人はサイトの色選びをどうしてるんだろう。

  • note

カードコンポーネントやレイアウトを参考にした。とくにレイアウトについては紆余曲折があった。「記事を並べるだけなら flexbox で事足りるな」と思って始めたが全然そんなことはなく変な隙間が空いたりコンポーネント間の gap が指定できなかったりで上手くいかないことが多かった。結果的に grid を使ってメディアクエリごとにカラム数を増減させる方法に落ちつく。

その他

  • mizchi.dev

    Next.js + MDX + AMP + TS のブログ。表示がめちゃくちゃ速いことに感動して Next.js でブログを作るきっかけとなった。Next だけでもまあ速いので本ブログの AMP 化はひとまず見送る。

さいごに(雑感)

スプラトゥーン 2 をしつつ、とりあえずブログを作るにあたって悩んだところ・はまったところを記事化していく。