(OSS向け)ドキュメントツールDocusaurus

No OSS, No Life. 
これは[OSS紹介 Advent Calendar 2017](https://qiita.com/advent-calendar/2017/favorite-oss) の24日目の記事です。

2017/12月中旬にFacebookがリリースしたドキュメント管理ツール[Docusaurus](https://docusaurus.io/)を試してみて、なかなかよかったので紹介記事を書きます。
Docusaurusは[GitBook](https://github.com/GitbookIO/gitbook)と同種のツールですが、（素の状態では）GitBookよりちょっと高機能という印象です。

こんな感じのドキュメントが手軽に作られます。
![ss-1.png](https://qiita-image-store.s3.amazonaws.com/0/25588/b0a2f080-757c-6a9e-b273-3cbdd5bb8d55.png)

公式ドキュメント: https://docusaurus.io/ （これ自体もDocusaurusで作られています）
リポジトリ: https://github.com/facebook/docusaurus

# 特徴とか機能とか

* マークダウンで書ける
* レイアウトをReactで書ける
* 検索機能
* i18nにも対応
* バージョニング対応
* GitHub Pagesに簡単にデプロイできる


# 導入

## セットアップ手順

### 1. 何はともあれ docusaurus-init をインストール

```sh
[~] $ yarn global add docusaurus-init
# or `npm install --global docusaurus-init`
```

### 2. プロジェクトディレクトリのルートで初期化コマンドを実行

```sh
[~] $ cd project
[project] $ docusaurus-init
```

この段階でルートに `docs-examples-from-docusaurus` と `website` というディレクトリ(スケルトン)が作成されますが、そのままでは設定とディレクトリ名が合っていなくて動かない状態です。

### 3. 作成されたディレクトリが適切になるようにリネーム

```sh
[project] $ mv docs-examples-from-docusaurus docs & mv website/blog-examples-from-docusaurus website/blog
```

ここまでで以下のような状態になっているはずです。（もちろん既存のsrc等も）

```
project
  ├─ docs (from docs-examples-from-docusaurus)
  └─ website
     └─ blog (from blog-examples-from-docusaurus)
     └─ core
     └─ node_modules
     └─ pages
     └─ static
     └─ package.json
     └─ sidebars.json
     └─ siteConfig.js
```

### 4. さっそくローカルwebサーバを起動

```sh
[project] $ cd website
[project/website] $ yarn start
```

### 5. `http://localhost:3000` を開く

自分の場合は初回アクセス時にエラーとなりましたが、リロードすると正常に表示されました。（初回にエラー返しつつ、ビルドしている？）


**注意点**

既存のmdファイルの変更は大丈夫ですが、それ以外の以下のような操作はホットに反映してくれないようです。

* 新しいmdファイルの追加
* siteConfig.jsの変更


## 概要

表示されるページのイメージとソースファイル等の関連は下図の感じです。

![ss-2-note.png](https://qiita-image-store.s3.amazonaws.com/0/25588/b8f75937-5667-b2aa-7051-d0f8d86d5964.png)


# 検索機能の有効化

検索機能は外部API([Algolia DocSearch](https://community.algolia.com/docsearch/))を利用しているため、まずはそちらの登録＆APIキーの取得が必要です。
取得APIキーをsiteConfig.jsで指定して、headerLinksに { search: true }を指定すればいいようですが、今回は試していません。


# i18nの有効化

## 1. 下記コマンドを実行して言語ファイル等を作成

```sh
[project/website] $ yarn examples translations
```

`website/pages/en/help-with-translations.js` というファイルが作成されるので、リネームして既存の `website/pages/en/help.js` を置換します。

ちなみに違いは、以下のようにtranslateをrequireして翻訳部分を囲んでいるだけなので、その他のファイルも同様にできます。

```
const translate = require("../../server/translate.js").translate;

<translate>This is english</translate>
```

## 2. 選択可能な言語を選択

1で `website/languages.js` が作成されているはずなので、ファイルを開きサポート言語を `enable: true` にします。

## 3. 翻訳する

おそらく今までにサーバを起動していたら、 `website/i18n/en.json` が出来ているはずで、そこに原文が記載されているので翻訳します。
一応Docusaurusは `website/i18n/en.json` を [Crowdin](https://crowdin.com/) にアップロードして一括翻訳し結果をダウンロードすることを想定しているようですが、必須ではありません。
今回は `website/i18n/en.json` をコピーし `website/i18n/ja.json` を作成し自前で翻訳しました。
ちなみに任意のページをロードした際に、対応するキーが辞書ファイルに存在しない場合は`website/i18n/en.json` に動的に追加されていきます。

## 4. ヘッダーで言語切替リンクを有効にする。

siteConfig.jsのheaderLinksに以下のように追加するだけです。

```
const siteConfig = {
  headerLinks: [
    ...
    { languages: true },
    ...
  ],
```


# バージョニング

## 1. 下記コマンドを実行し、バージョンファイルを作成

```sh
[project/website] $ yarn examples versions
```

`pages/en/versions.js` が作成されます。

## 2. 下記コマンドを実行し、当該バージョンのドキュメントを作成

```sh
[project/website] $ yarn run version 1.0.0
```

`1.0.0`の部分は自由です。
`website/versioned_docs/version-1.0.0` や `website/versioned_sidebars` が作成されます。
それらの中身は現在のdocsやsidebars.jsonがコピーされています。（単純コピーではなくドキュメントID等がよしなに書き換えられている）

## 3. ヘッダーに表示する

```
const siteConfig = {
  headerLinks: [
    ...
    { page: "versions", label: "Version" },
    ...
  ],
```

# GitHub Pagesへのデプロイ

## 1. まずはビルド

```sh
[project/website] $ yarn build
```

`webite/build` にビルドされたファイル類が作成されるので `.gitignore` に指定していない場合は追加しておくといいと思います。

## 2. おもむろにデプロイ

```sh
[project/website] $ GIT_USER=xxx yarn publish-gh-pages
```

環境変数GIT_USERにはGitHubのユーザ名を指定します。

**注意**

* siteConfig.jsに `organizationName` と `projectName` が必要です。（もしくは環境変数 `ORGANIZATION_NAME`, `PROJECT_NAME`で指定する）特に`organizationName`は初期状態だとコメントアウトされているのでコメントを解除する。


--

以上です。i18nとバージョニングを組み合わせたときにハマりましたが、それ以外は思ったよりも簡単に試すことが出来ました。
今回はやっていませんが、CIとの統合もできるようです。