Edited at

GitbookユーザはRust製mdBookを使うと幸せになれる、かも

More than 3 years have passed since last update.


要約



  • mdBookはGitbookにインスパイアされてるRust製ドキュメントビルダー

  • Rust製なのでぶっちぎりに速い、メモリとCPUに優しい

  • 諸々足りない部分はあるが、ある程度運用でカバー出来る


履歴


  • 2016.06.07 mermaid.jsの読み込みと図のレンダリングについての記述を追加


はじめに

社内のドキュメント整備を行うに当たり、まあどうせならバージョン管理しながらテストもしたいし、体系的に纏められるGitbookがいいよね、って話になりました。んで、既存のドキュメントなんかもGitbookにドンドン移行してました。

私は普段、エディターはAtomを利用し、gitbook serveコマンドでwatch & HotReloadをさせながら表示項目を確認しつつ、ツラツラと作成してました。

基本的には push->CI(ビルド&テスト)->デプロイ を繰り返す環境です。

ドキュメント作成も開発スタイルに則ろうぜ!という試み。


Gitbookが遅い

ドキュメントの数が少ないうちは全く問題ありませんでしたが、20,30と増え続け50を超えた当たりから辛くなってきました。

特にGitbook3.0以降、極端に遅くなり、serveでホットリローディングを行うのに毎回10秒を超える事がザラです。atomのmarkdown previewでいいやん!って話ですが、ドキュメントの構造を確認しながら作業をしたかったため、serveを手放したくなかったのです。

現在100程度のmarkdownファイルが存在しますが、プラグイン類全部切っても10秒以上かかります、これは辛い。ちなみに同様の意見はissueにもかなり上がっており、参考にしながら対策を試みましたが、劇的な改善はありませんでした。


mdBook

そんなわけでmdBookの登場です。

Gitbook flavorなドキュメントビルダーでRust製、この時点で惹かれます。

イニシャルコミットがちょうど去年の今頃なので、ポッと出のツールでは無さそうです。

活発というほどではないですが、継続してコミットされてます。

ドキュメントはこちら


利用方法

rustのパッケージマネージャ cargo を利用します。その他のインストール方法はこちら



  1. cargo をインストール、またはbrew install rustでもいける


  2. cargo install mdbookでmdBookをインストール

  3. パスを~/.cargo/binに通す(mac osの場合)

以上で利用準備は完了。


bookを作ってみる

mkdir mdBook-test

cd mdBook-test
mdbook init

// .gitignoreファイルを作るかどうか聞かれる
Do you want a .gitignore to be created? (y/n)
y

All done, no errors...

上記でmdBook-testディレクトリに作成されます。ストラクチャはこんな感じ。

.

├── book
└── src
├── SUMMARY.md
└── chapter_1.md

srcディレクトリにmarkdownファイルを入れて、ビルド後のファイルはbookに入るイメージ。ちょっとこの辺がGitbookと違います。SUMMARY.mdの役割はGitbookと同一です。


serveしてみる

mdbook serveで可能。

mdbook serve

[*] Creating "/dev/mdBook-test/book/chapter_1.html" ✓
[*] Creating index.html from "/dev/mdBook-test/book/./chapter_1.html" ✓
[*] Creating print.html ✓

Listening for changes...

この状態で、http://localhost:3000 でアクセスしてみます。

localhost_3000_1.png

すごくシンプルですが、Gitbookぽい画面が表示されました。


パフォーマンスチェック

ファイル数が少ないと全く恩恵がわかりませんが、ある程度の量を使ってビルドパフォーマンスを検証してみます。

まずはGitbookから。

gitbook serve

Live reload server started on port: 35729
Press CTRL+C to quit ...

info: 7 plugins are installed
info: loading plugin "mermaid-2"... OK
info: loading plugin "livereload"... OK
info: loading plugin "highlight"... OK
info: loading plugin "lunr"... OK
info: loading plugin "sharing"... OK
info: loading plugin "fontsettings"... OK
info: loading plugin "theme-default"... OK
info: found 76 pages
info: found 86 asset files
info: >> generation finished with success in 12.7s !

この時点で 76のmarkdownファイル86のassetファイル(画像など) が存在します。ビルド時間は 12.7sec、かかりすぎです。

続いて、全く同じ構成でmdBookを利用します。

標準ではビルド時間は測定されないため、元リポジトリをクローンし、コードをいじってます。(ちなみに初Rust)

対象はserve実行時のcreateならびにcopyファイルの総時間。

mdbook serve

Serving on localhost:3000

Listening for changes...

...

[*] Copying file: "/src/images/test.png"
to "/book/images/test.png"

180561000 //ナノ秒出力≒180ms

5回の計測を行ったところ、平均250ms程度。 約50倍の高速化となりました。


メモリ使用量

gitbookの場合、serveが実行されている最中に大きくメモリを消費します。

具体的には 400-500MB の間、更新が走ると基本CPU使用率が 100% 超えます。

PID   COMMAND      %CPU  TIME     #TH   #WQ  #PORT MEM    

6080 node 102.7 00:28.60 16/1 4 49 396M+

一方のmdBookは優秀です。 約8.5MB と考えると50分の1程度にはなっています。

CPUの使用率も同環境で瞬間的に10~15%程度でした。

PID   COMMAND      %CPU TIME     #TH   #WQ  #PORT MEM

6099 mdbook 0.0 00:00.52 38 1 68 8480K

もうちょいマシなベンチマーク方法もあるんでしょうが、それはまた後日にでも。

体感速度も全くストレス無いレベルまで改善されました。


mdBookの難点

とはいえ、以下の問題が。


  • pdf/ebookへの出力が出来ない

  • カスタムしたwebsite.cssが合わない

  • ディレクトリ構成がGitbookと違う

  • gitbook-pluginが使えない

pdf/ebookへの出力は、まあGitbookでやればいいや。

website.cssも、ローカルではまあいいや・・・

ディレクトリ構成については、後述。

gitbook-pluginに関しては当たり前と言ってしまえば当たり前なんですけど。

ただ、mermaid.jsをバリバリ使ってた身としては辛いのでここはなんとかしたい。


mermaid.jsをなんとかする

mdBookはテーマの拡張handlebarsで出来るとのこと。

なので、ここからmermaid.jsを読み込む指定をします。


  • srcディレクトリにthemeディレクトリを作成し、index.hbsを作成

cd src && mkdir theme

touch index.hbs

ストラクチャはこんな感じ

.

├── README.md
├── SUMMARY.md
└── theme
└── index.hbs

index.hbsはgistにあげましたので、こちらをDLしてください。

標準のテンプレートから変更点は下記のみです。


index.hbs

<!-- mermaid.js -->

<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mermaid/6.0.0/mermaid.min.js"></script>
<script>
$('pre .language-mermaid').each(function () {
$(this).html('<div class="mermaid">' + this.textContent + '</div>');
});
</script>


  1. cdnからmermaid.jsを読み込み

  2. jQueryでDOM書き換え

の2点だけです、jQuery久しぶり過ぎて忘れてるんですが、これで多分問題ないはず。。

これでmdBookでmermaidの図が表示されるようになりました。

なお、mermaid側にもいくつかテーマが存在し、その中でもforestを使っていたのですが、 なんとmdBook側のcss と競合し、サイドバーが悲しいことになります。

そのため<head></head>部分には記述してますが、現在はコメントアウトしておきました。

これ完全にmermaid側のCSSが悪いです、issueにも上がってるけど。。

無論css上書きでどうにかなる問題ですので、お好みでどうぞ。


個人的運用方法

既存のGitbookとmdBookをどう連動させるか模索してまして、個人的には下記に落ち着きました。


  1. 既存のGitbook内でsrcディレクトリ作成

  2. markdownファイルとassetsファイル系を全てsrcに移動

  3. Gitbookのbook.jsonのrootをsrcに指定

  4. .gitignoreに/bookを追加


  5. mdbook serve実行

あまり既存ディレクトリを弄りたくなかったんですが、book.jsonのroot指定が簡単かつ相対パスリンクも崩れないため、これで良いやってなりました。

んで、serveしながら、


  1. ローカルでのファイル編集とホットローディングはmdBookで

  2. ある程度溜まったらpush

  3. CIビルドはGitbookで行う

  4. デプロイ

ようはローカル側ではmdBook、本番への適用はGitbbokを使ってビルド、ってことです。プラグインのこともありますし。

作図はatom-mermaidを使わせていただき、形が整ったらドキュメント側にコピ貼りしてます。

今のところ、上記運用で大きな問題は出てません。


最後に

どうでしょう?幸せになれました?まだまだ発展途上感ありますが、個人的にはそこそこ満足です。

あと、Rust面白いですね、これから継続的に触りたい。

mdBookのプラグインが増えつつ(増やしつつ)、発展を願います。