SSGフレームワーク「Docusaurus」を試してみた

GatsbyやNextに次ぐSSGの新しい選択肢

Soudai Sasada

Soudai Sasada

最近Twitter広告で流れてきたフロントエンドエンジニアの海外求人を見てみたらDocusaurusの利用経験が優遇条件として挙げられていました。Docusaurusを知らなかったのでググってみたところ静的サイトジェネレータのようで、Reactを作ったFacebook製ということもあり気になったのでこの機会に調べてみることにしました。

インストール

Docusaurusではnpxコマンドが用意されています。ドキュメントのとおりインストールしてみましょう。コマンドへ渡す引数は以下の通りです。

npx @docusaurus/init@latest init [name] [template]

それではインストールします。今回は公式で用意されている classic というテンプレートを使用します。このテンプレートでは2つのテーマと7つのプラグインがバンドルされドキュメントやブログの管理、カスタムページの作成やサイトマップの生成などの基本的な機能が用意されています。

npx @docusaurus/init@latest init my-website classic
Need to install the following packages:
  @docusaurus/init@latest
Ok to proceed? (y) y

Creating new Docusaurus project...

Installing dependencies with yarn...

実行すると対話形式で@docusaurus/initパッケージをインストールしても良いか尋ねられます。そのまま進めたところ依存はyarnで解決されるみたいでした。実際に試していませんがソースコードを見たところ --use-npm オプションを渡せばnpmで依存を解決できるかもしれません。

さて、そのまま依存関係の解決が済むと起動を勧められます。

[4/4] Building fresh packages...
success Saved lockfile.
Done in 52.36s.

Successfully created "doc".
Inside that directory, you can run several commands:

  yarn start
    Starts the development server.

  yarn build
    Bundles your website into static files for production.

  yarn serve
    Serve the built website locally.

  yarn deploy
    Publish the website to GitHub pages.

We recommend that you begin by typing:

  cd doc
  yarn start

Happy building awesome websites!

早速やってみました。

$ cd doc
$ yarn start

するとlocalhost:3000にサイトが公開されました。こんな感じです。

docusaurus-top

docusaurus-create-page

ドキュメントの管理ツールとしての機能が一通り実装されているみたいで用意されているコンテンツがDocusaurus自身のドキュメントとなっているようです。デフォルトでダークモードが用意されているあたり時代を感じますね。

作ってみる

作成できるページは大別して以下の3種類になります。

  • カスタムページ
  • ドキュメント
  • ブログ

それぞれソースコード上でどこにファイルを設置するかで識別されます。

カスタムページ

カスタムページとは「独自コンテンツ」のこととなります。

カスタムページでは後述するドキュメント、ブログ以外のサイトのページを作成可能で src/pages 以下にファイルを設置することでそれがそのままサイトのパスとして扱われます(例えば src/pages/404.js はサイト上で /404 に展開されます)。

基本的にマークダウンファイル(.md OR .mdx)でサイトを構築するDocusaurusですが、カスタムページのみJSXでの構築が可能となっておりドキュメントやブログといったフォーマットに縛られないような独自のページを作成する場合に適しています。

ドキュメント

ドキュメントとは「バージョン管理できるストック型コンテンツ」のこととなります。

docs ディレクトリに配置されたマークダウンファイルのみがドキュメントの対象となります。設置したドキュメントファイルはそのままサイトの /docs 以下に展開されます(例えば docs/intro.md はサイト上で docs/intro に展開されます)。

ドキュメントページでは両サイドにサイドバーが用意されており、左サイドバー上ではドキュメント内の各ページが、右サイドバーでは現在のページ内のアンカータグがリンクとして設置され、どちらのサイドバーも階層構造まで表現されています。

左サイドバー

左サイドバーでは他のドキュメントのリンクがソースコード内の階層構造をそのまま表現した形で設置されます。このとき同一階層間でのサイドバーの位置はドキュメントのFront Matter上で sidebar_position に表示順序を指定することで管理可能です。
ネストした階層はやや特殊で、ディクレトリに _category.json というJSONファイルを設置し label で表示名を、 position で表示順序を設定する必要があるようです。

例えば次のようなディレクトリ構成となっているとします。

docs/
├─ docs/intro.md              # sidebar_position: 1
├─ docs/tutorial-basics/
|  ├─ _category_.json         # label: "Tutorial - Basics", position: "2"
|  ├─ create-a-page.md        # sidebar_position: 1
|  ├─ create-a-document.md    # sidebar_position: 2
|  ├─ create-a-blog-post.md   # sidebar_position: 3
|  ├─ markdown-features.md    # sidebar_position: 4
|  ├─ deploy-your-site.md     # sidebar_position: 5
|  └─ congratulations.md      # sidebar_position: 6
└─ docs/tutorial-extras/
   ├─ _category_.json         # label: "Tutorial - Extras", position: "3"
   ├─ manage-docs-versions.md # sidebar_position: 1
   └─ translate-your-site.md  # sidebar_position: 2

これはこのように表示されます。

docusaurus-sidebar-left

右サイドバー

右サイドバーには現在のドキュメント内のアンカータグが設置されます。h1を除いた全ての見出し要素が自動的にアンカータグとなるため自身で特別な操作をする必要はありません。サイドバーに表示されるのはh2とh3のみの2階層までとなり見出し要素のヒエラルキーがそのままサイドバーの表示にも反映されます。
なおh1はページの見出しとして1つ目のみがアンカータグとして認識され以降に登場するh1はアンカータグが生成されません。また、h1は記事の冒頭に表示することが期待されているためサイドバーにも表示されることはありません。

例えば次のようなドキュメントがあったとします。

# Tutorial Intro

Let's discover **Docusaurus in less than 5 minutes**.

## Getting Started

Get started by **creating a new site**.

Or **try Docusaurus immediately** with **[docusaurus.new](https://docusaurus.new)**.

### hoge?

hoge

#### fuga?

fuga

##### piyo

piyo

###### hogehoge

hogehoge

## Generate a new site

Generate a new Docusaurus site using the **classic template**:

## Start your site

Run the development server:

これはこのように表示されます。

docusaurus-sidebar-right

バージョニング

ドキュメントではバージョニングをサポートしています。
バージョニングをする場合には docs ディレクトリのほかに versioned_docs というディレクトリがプロジェクトルートに配置され versioned_docs ディレクトリ直下ではバージョンディレクトリを設置することでそのバージョンのドキュメントを管理でき、バージョンディレクトリ内で最新のバージョンがサイト上でのlatestバージョンという扱いとなり docs ディレクトリに配置されたドキュメントはnextバージョンとして扱われます。
nextバージョンが無事リリースされた場合には次のコマンドを打つことでバージョニングを進めnextバージョンに配置されていたファイルを自動でバージョニングディレクトリに移動したり他にバージョニングのために必要な処理を全てDocusaurusが実行してくれます。

$ yarn run docusaurus docs:version 1.1.0

このあたりはドキュメントをご覧いただいた方が分かりやすいかもしれません。

ブログ

ブログとは「公開日ベースで並びタグ付けが可能なストック型コンテンツ」のこととなります。

blog ディレクトリの直下に配置されたマークダウンファイルのみ(サブディレクトリ、例えば blog/hoge/* は対象外)がブログの対象となります。設置したブログファイルはファイル名に関わらずFront Matterに記述された slug をサイトのパスとして展開されます(例えば blog/2019-05-28-hola.md というファイルがありファイル内のFront Matterにあるslugで hoge/fuga と指定されていればサイト上では blog/hoge/fuga に展開されます)。
また、Front Matterにある date でブログの公開日を設定できますが、これを指定しない場合はブログのファイル名の先頭が YYYY-MM-DD から始まる場合にそれを公開日としてサイト上に展開し、 date もファイル名の先頭にも日付がない場合はブログファイルを作成した日付が公開日となります。ファイル名で日付を設定する場合は日付以降の文字列はコンテンツに影響しないので 2019-05-28.md というファイル名でも問題ありません。

ブログはコンテンツのページのほかに一覧ページが用意されておりヘッダーやフッターに設置されるリンクからは一覧ページへ飛ぶことができます。一覧ページでは公開日順にブログが並んでいます。また、個々のブログにタグ付けをすることでコンテンツ上にタグのリンクが表示されますがそこからそのタグが付いているブログを一覧上で探せるようになっています。

docusaurus-blog-list

ブログでは他にも様々な機能が用意されています。ドキュメントはこちらになります。

触ってみた感想

ここまで紹介した他にもAlgoliaによるサイト内全文検索のサポートi18n対応サイトマップの生成など便利な機能があり、標準テンプレートを利用することで必要な機能が網羅されているという点でGatsbyと比較してみて特定の用途において非常にイージーなフレームワークだと感じました。
これは静的サイトジェネレータの中でもドキュメント生成ツールとして利用用途を絞っているために実現できていることであり、また、その結果としてドキュメントサイトを構築するうえで必須となる機能が一通りビルトインで提供されているためです。
一方でドキュメント生成ツールとして特化していることで非エンジニア職の方がサイトを更新するのはややハードルが高いのではないかと感じました。これはドキュメントのバージョニングにnpm-scriptsが必要になったり各種のjsonファイルでドキュメントやブログを管理する必要があったりと、Docusaurusの運用方法を理解したうえでソースコードを直接編集する前提でDocusaurusが作られているためです。Headless CMSとの連携もサポートされていなさそうでした(ちゃんと調べきれていないため誤っていたら申し訳ございません)。
この辺りについてはドキュメントという性質上なによりも正確性が求められますしそういった意味では「ソースコード上で記述しレビューのフローに組み込む」というのは必要なプロセスとして割り切っているのではないかと考えています。

細かい設定やデプロイまでやったわけではないのでハマりどころがないかと言えばまだ分かりませんが少なくともドキュメントやブログ周りの機能はDocusaurusを使うことで文章の作成にフォーカスできそうだという感触を得られました。
ドキュメントを作成する際には利用を前向きに検討してみようと思います。

この記事がお役に立てたら一杯のコーヒーを恵んで頂けると励みになります 😊

Buy Me A Coffee
© 2020, Soudai Sasada