技術ブログを支える技術(Gatsby + esaio)

2018.12.01

2018年5月に公開を始めた当ブログですが、Gatsbyをより多くの人に使ってもらいたいと考えソースコードをオープンにしたので、ブログで用いている技術について説明します。

当サイトについて

Gatsbyでesa.ioのデータを使って静的サイトをビルドする構成のリポジトリです。Netlifyでホスティングしています。

https://github.com/mottox2/website スターがつくとやる気がでます。

ポイント

Gatsbyについて少し知っている前提で中身を説明します。

esa.ioをソースとして扱う(gatsby-source-esa)

Gatsbyではファイルシステム上のファイルだけでなく、Web APIなどを経由した様々なデータをソースとして扱う仕組みを持っています。 ソースとして扱われるデータはビルド中に処理され、静的ファイルとして書き出され、本番に公開されてもデータ元へのアクセスは不要になります。しかもCDNに乗せることができ早いです。

esa.ioは情報共有ツールですが、Web APIやWebhookといった開発者に馴染みの深い仕組みをもっています。しかし、APIには15分に75リクエストという制限があります。 ただ、Gatsbyのソースとして扱えば、ビルド時にしかAPIを叩くことはないので、APIの利用制限はほとんど影響がなく利用することができます。

そのesa.ioの記事をsourceとして扱うためのプラグインがgatsby-source-esaです。

mottox2/gatsby-source-esa

TypeScriptに対応する(gatsby-plugin-typescript)

GatsbyはReactでViewを書いていきます。近年React+TypeScriptは流行っている印象があって、ReactコンポーネントのPropsに型をちゃんと設定しておくと呼び出し時に型チェックをしてくれます。 開発初期にはあまり効果を発揮しませんが、改修をする際にPropsのチェックがあることで安心してコードの変更を行うことができます。

Gatsbyは標準ではTypeScriptは採用していませんが、内部で利用しているwebpackの設定をいじるAPIがあり、そのAPIを叩いてくれるのがgatsby-plugin-typescriptです。

gatsbyjs/gatsby: /packages/gatsby-plugin-typescript

noteの記事をソースとして扱う

このブログを始める前にnoteで少し記事を書いていたので、水増しのためにnoteの記事もブログに掲載しています。 gatsbyにはgatsby-node.jsという挙動をいじるファイルがあるので、そのファイル内でnoteのRSSから得られたファイルをGatsbyのAPIを叩いてソースとして登録しています。

RSSを扱うプラグインはあったのですが、あまりイケてると思わなかったのでリポジトリ内で対応しました。f

該当コード: gatsby-node.js

gatsby-node.js
exports.sourceNodes = async ({ actions, createNodeId }) => {
  await parser.parseURL('https://note.mu/mottox2/rss').then((feed) => {
    feed.items.forEach(item => {
      const digest = createNodeId(`${item.link}`)
      actions.createNode({
        ...item,
        id: digest,
        parent: null,
        children: [],
        internal: {
          contentDigest: digest,
          type: 'Note',
        },
      })
    })
  })
};

タイトルを元に公開日時などのフィールドを作成する

情報共有ツールesa.ioをCMSとして使って1ヶ月運用してみた」の記事でも書いたのですが、esaにはTitle, Category, Tag, Contentぐらいしか入力項目がありません。 ブログとして必須と思われる公開日時が欲しいのでタイトルに「[2018-12-01] Gatsby+esaブログのソースコードを公開しました」と入力することで、公開日を指定する方式を採用しています。 これもgatsby-node.jsで挙動をいじることで実現しています。

該当コード: gatsby-node.js

gatsby-node.js
const DATE_REGEXP = / ?\[(.*?)\] ?/

exports.onCreateNode = ({ node, actions, createNodeId }) => {
  const { createNode, createParentChildLink, createNodeField } = actions

  if (node.internal.type === 'EsaPost') {
    createNodeField({ node, name: 'title', value: node.name.replace(DATE_REGEXP, '') })
    createNodeField({ node, name: 'excerpt', value: h2p(node.body_html)})

    // Extract the date part from node.name (ex. "[2018-10-08] I participated in Techbook Festival")
    const matched = node.name.match(DATE_REGEXP)
    const day = matched ? dayjs(matched[1]) : dayjs(node.updated_at)
    const dateNode = buildDateNode({ nodeId: node.id, day, createNodeId })
    createNode(dateNode)
    createParentChildLink({parent: node, child: dateNode})
  }
}

今後の展望

2018年12月1日現在の展望です。

まとめ

このような技術でブログを半年続けることができました。技術ブログを書くことで知識のインプット・アウトプットが行え、技術ブログを作ることでソースコードとしてのアウトプットを行えました。

ぜひ皆さんも「俺の考えた最強のブログ」をつくって、継続してみてください。