README.md書いてますか？ドキュメンテーションを強化する「docsify」の紹介

## 言いたいこと
docsifyはindex.htmlなどをビルドする必要がなく、CDNで作れるので管理者じゃなくても(Github)Dependabotに怒られなくなります。

### 導入方法
あまりにも簡単なので、先に紹介します。

1. [クイックスタートのindex.html](https://docsify.js.org/#/quickstart?id=manual-initialization)を作成する
1. `README.md`を普通に書く
1. `index.html`を開く

CDNの場合、動いているのはクライアントJavaScriptなのでlocalhostでも動きます。

- [公式ドキュメント](https://docsify.js.org/#/)
  - [有志による日本語ドキュメント](https://yamachan.github.io/docsify-docs-ja/#/)

## 発端
node系に限らずですが、`package.json`のようなものをpushすると、Dependabotがアップデートの状況などを管理してくれてとてもありがたいです。
が、反面Github Actionsで回している環境とローカルで開発したnodeなどのバージョンやライブラリの状態によってはDependabotのプルリクを通した後に開発ができなくなる、なんて事がありました。
当たり前ですが、Dependabotがアップデートした内容に準拠して開発環境も最新化・統一するのが当然なのですが、技術要件が高すぎてスキル差があるチームだとたかがドキュメンテーションなのに、うまく動かなくて詰むなんて事も。
開発でもnodeでREADME関連もnodeでビルドしていると、何が干渉しているか分からないので、どのパッケージを切り離して簡略化するか判断が難しく、結局READMEを捨てる、なんて事もありました。
新卒研修ではドキュメンテーションも評価の対象である事もあり、これでは何のために開発をしているのか分からなくなります。

docsifyはREADMEのビルド環境をすべてCDNに移管する事ができます。
私にとって（特に新卒研修などで受講生側が多少スキルがあるケース）にとっては神のようなツールです。

### 懸念
CDNもDependabotのように最新化されると動かなくなるケースというのは考えられます。
対応策としては、

| 手段 | 検討事項 |
| --- | --- |
| `docsify.js`をバックアップしておく | 開発でnodeを使うケースを想定していますが、npmなどに組み込まなければ開発環境を汚染しません |
| docsifyを捨てて、異なるビルド環境を構築する | 今までのやり方に戻す案です。リスクは先述の通りです。 |
|`marked.js`を使う（index.htmlにmarkdownを書く・流し込む） | 環境を守りつつ代替方法としては優秀ですが、手間がかかります。<br>また、docsify同様、バージョンアップによって環境が破壊されるに可能性を考慮しておくべきです。 |
| GithubやGitLabなどの標準機能を使う(Git系ユーザー) | 多分これが一番ベストだと思います。資料を完全に内部向けと割り切るため、外部公開する場合は別のオープンリポジトリにdocsだけ移行すると良いでしょう。<br>Netlifyをはじめとしたホスティングサービスを使う方法もあります。 |

などが考えられます。
（細かい事をいえば、Git系ユーザー向けの方法もサービスを使う以上、サービス側の追加機能や仕様変更の煽りは絶対に受けるハズですが、影響が大きすぎるのでやらないんじゃないかという願望です）

### ケースバイケースで見る対策
これだけいっぱい書いてますが、ぶっちゃけ開発で使う場合に気にすれば良いかなと思います。
特に作って後悔した後は投げっぱなしになる個人開発アプリを転職活動などで成果物として提出する場合です。
この場合は、どうせ個人と開き直って、githubのオープンリポジトリあるいは採用者向けのprivateリポジトリを作って、そちらのREADMEだけを使うパターン（docsifyを使わない）が最も良いかと思います。
非エンジニア（あるいは、Not Githubユーザー)にとっては画面として若干見にくくなりますが、リポジトリ自体またはGithubアカウント自体をポートフォリオサイトとして位置付ける方法があります。

有名どころだと、

- `(ユーザー名)/(ユーザー名)` のリポジトリは特殊リポジトリになる
- `(ユーザー名)/(ユーザー名).github.io` のリポジトリは、GithubPagesのルートになる

ですね。
その他にも使い方はありそうな気がしますが、今も昔もググラビリティが壊滅的すぎて情報を集めるのが難しいです…

#### 研修時の判断について
新卒研修ぐらいの短い期間なら気にしなくて良いと思いますが、たとえば１年間指導するようなケース（個人指導・ITスクール事業社の個人向けパッケージなど）は、今回のケースが発生する可能性が高いと思います。
「ドキュメンテーションにリソースを使うべきではない」という観点から、導入時の最新版をバックアップしておき、CDNがダメになった場合に備えておくのが現実的な運用かなと思います。

なお、ドキュメンテーションを採点しない場合はdocsify自体が不要です。
採点する場合は、githubのREADME.mdで評価するのは正しくなく、古い文化を継承しているクライアントの場合、ドキュメントページを印刷(.pdf)してレビューします。
（これはクライアントが古いのではなく、クライアントのエンドが古い体質である可能性も想定しておいてください。）

### 考え方
ここで言いたいのは、docsifyに限らず現環境が壊れた際にリカバリーや代替手順が存在するか？という事です。
あるあるですが、Java研修などでEclipseを使って開発する場合は、Eclipse自体がしょっちゅう壊れます。
代替案としてJetBeansのIntellJ IDEA(Community Edition)などが挙げられますが、残念ながら運営側・講師ともにEclipseと比べると知見がないため採用される事はまずありませんでした。
Eclipseもバニラで使うだけなら乗り換えも容易ですが、たとえばプラグインを入れたり（OJDBCとか)端末依存の設定をする場合は、IntellJ IDEAのどこを設定すればできるのか、手順（マニュアル）化してから受講生に配布し、確実に問題を起こさないようにするという担保が必要です。
実際問題として、研修パッケージの提案段階ではこの観点がスッポリ抜け落ちているんじゃないかと思われるため（disりたい訳ではなく、実情のお話をお伝えしています）、この辺りも含めて「障害発生時の対応」という括りで合意締結されているように思います。

本稿では、上記観点も含めてdocsifyを採用するメリットを強調したくて執筆しています。

## Q. docsifyはJAMStackか？
A. JAMStackではありません。

こんな事を気にする人はいないと思いますが、SSGっぽい使い方ができるので、これには言及しておいた方がいいかなと思いました。
まず、`index.html`などを生成しないため、SSGではありません。
`marked.js`は既に生成されている`index.html`内の内容を読み取ってmarkdownをhtmlタグなどに置き換えていますので、これも違います。
ただし、これらは動的ページではありません（＝サーバーにリクエストがないため、高速ですがサイト内検索やコメント機能は別途作成する必要があります）
また、静的CMSでもありません（＝docsifyにコンテンツ管理機能はありません）
強いていえば、markdownからhtml要素を生成して出力する膨大なJavaScriptです。

ポートフォリオ等を作成する際に、JAMStackでなければならない要件であれば採用しないように注意してください。

## Docsifyで静的CMSのような事をやりたい
現状だとCIを使ってwebhookをトリガーする方法でしょうか。
外部にCMSを置く事になるので、Doscifｙ自体は静的CMSにならないのが、質問への回答としてズレてしまうポイントになります。

実はアドベントカレンダーの記事はすべて手前味噌のDocsifyに流し込んで仮運用しています。
Qiitaの投稿のバックアップは取っていますが、これがmarkdown形式なので、後はdocsifyのルールに従ってファイルを配置していけば、（バニラだと）レイアウトこそ異なりますが、やりたい事自体はできています。

ただし、qiitaの記法はdocsifyでは認識できないので、置換する仕組みは作る必要があります。
あるいは、運用対処としてqiita独自の記法を使わないのもありますね。
幸い、目次に関してはqiitaもdocsifyも独自機能でサポートされているので、ここの競合はありません。

## 次の記事
- [(12日目) 【LT】エンジニア目線で考える「サービスの質」を考える](https://qiita.com/nomurasan/items/1c690d8455a26aa22b8a)
- [カレンダーページ](https://qiita.com/advent-calendar/2022/oreno_nomurasan2022)