Elm Advent Calendar2017、今年は去年よりも大いに盛り上がっていて、沢山の人達が沢山の情報を上げていて、毎日楽しく拝見しております。
それでは最終日、行かせて頂きます。
社内向けドキュメントの展開
ワタクシの務めるFringe81ではElmを用いたプロダクトが現在2つ稼働しています。
3つめ4つめも仕込んでいくような気配もあるので、徐々に社内共通で使うライブラリも作り出したりするようになってきました。
さて、このライブラリ、仮にElm Packagesで一般向けに公開しようとなるとあらゆる人に使いやすく設計する必要があるため、グッと敷居が高くなるんですが、プロダクト開発速度を考えると結構な労力を使って一般化レベルに持っていくまでの余裕は無かったり。
という事で、社内最適化を考えたときに、社内スコープでドキュメントを参照してもらいたいという欲求に対する1つのパターンを提示できればなーと思います。
さらにドキュメントはElm Packagesの体裁で一貫性を持たせていこうと思います(カッコイイですよね♪)。
全体の流れ
ステップとしては下記のような感じです
ソースコードにコメント書く
-> ソースコメントからドキュメントファイルを生成
-> テスト表示
-> ドキュメントサイト構築
-> 公開/展開
ドキュメントの記述
ドキュメンテーションフォーマットに関しては公式ガイドがあります。まずテキトーに作ったアプリケーションをもとに、このガイドに沿ってコメントを付けていきたいと思います。
モジュールが複数あったほうが応用が聞くと思うので、Main.elmと、モデルの知識をカプセル化したTypes/Model.elmの2モジュールを作ってみます。
module Main exposing (Msg, init, main, update, view)
{-| This application offers transforming a model into gained or losing.
# Definition
@docs Msg
# Determine a next model.
@docs init, update
# Create view
@docs view
# Entry point
@docs main
-}
import Html exposing (Html, button, div, span, text)
import Html.Events exposing (onClick)
import Types.Model as Model exposing (Model)
{-| All of action of this Application.
-}
type Msg
= Gain
| Lose
{-| Initial model and effects.
-}
init : ( Model, Cmd Msg )
init =
( Model.initial, Cmd.none )
{-| Updating model and generating effects.
-}
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
Gain ->
( Model.gain model, Cmd.none )
Lose ->
( Model.lose model, Cmd.none )
{-| Create views of this application.
-}
view : Model -> Html Msg
view model =
div []
[ button [ onClick Lose ] [ text "lose" ]
, span [] [ text <| toString model ]
, button [ onClick Gain ] [ text "gain" ]
]
{-| The entry point of this application.
-}
main : Program Never Model Msg
main =
Html.program
{ view = view
, init = init
, update = update
, subscriptions = always Sub.none
}
module Types.Model exposing (Model, gain, initial, lose)
{-| This module have a knowledge of model.
For example, a initial state and a way of how to change it.
# Definition
@docs Model
# Initial Model
@docs initial
# Changing Model
@docs gain, lose
-}
{-| Type of model.
-}
type alias Model =
Int
{-| Initial model.
-}
initial : Model
initial =
0
{-| Change a model to gained form.
-}
gain : Model -> Model
gain m =
m + 1
{-| Change a model to lost form.
-}
lose : Model -> Model
lose m =
m - 1
ドキュメントファイル生成+簡易閲覧
Elm Packagesのドキュメントは専用のJSONフォーマットを読み込んで生成される模様。
準備としてelm-package.json
のsummary
にプロジェクト概要、exposed-modules
に下記のようにドキュメント化したいモジュールを記述します。
{
...
"summary": "Sample Application",
...
"exposed-modules": [ "Main", "Types.Model" ],
...
}
そしてコンソールを開いたらプロジェクトルート上で下記コマンドを流します。
elm-make --docs=documentation.json
これでdocumentation.json
が生成されたと思います。
このファイルを公式のドキュメントプレビューガイドで開いてみましょう。
でました!おなじみの「あの感じ」で。
一応、会社内のElmer達に向けてこのページを開いてJSONファイル食わせてくれー、とお願いする運用も可能ではあるんですが、リロードすると消えちゃいますし、使い勝手が悪い!ということでもう少し運用し易い形に持っていきたいと思います。
elm-docでドキュメントサイトを構築
elm-docさんを使うことで、一時的ではなくドキュメントサイトのブツを残すことが出来ます。なんて素晴らしいライブラリ!
利用者から見た簡易構築手順もサラッと残しておきます。
Python環境の構築
elm-docはPythonを利用するようなのでまずは下記を準備します。ワタクシはpyenvを使って3.4.3にしました。
- pythonのバージョンを3.4以上に上げる
- python-magicをインストール
elm-docのインストール
pip install --upgrade pip setuptools
pip install elm-doc
elm-docでドキュメントサイトをビルド
elm-docのREADME.mdを読めば、ファイル除外など色々とオプションがありますが、今回はスタンダードに。
プロジェクトルートで下記を実行します。
elm-doc . --output docs
これでdocs
というディレクトリ、配下にファイル群が生成されると思います。
閲覧環境を構築
このdocs
ディレクトリを社内サーバーで公開すれば完了でございます。
ただ、社内ライブラリということで、社内のElmersがカスタマイズしてプルリクしてくれるというシナリオも想定して、ローカルでの最新のドキュメントを参照しやすい方法も構築します。
今回は、openerとnode-web-serverを使います。
まずはインストール。
npm i -D opener node-web-server
次に、プロジェクトルートにサーバーの設定ファイルを生成します。
{
"host" : "localhost",
"port" : 4000,
"docRoot" : "docs",
"allowUnknownMIMEType": true,
"MIME" : {
"": "text/html"
}
}
package.jsonにスクリプトを設定します。ポートは4000としてみます。
{
...
"scripts": {
"doc": "./node_modules/.bin/opener http://localhost:4000 && ./node_modules/.bin/nws -c server.conf"
},
...
}
これでブラウザが開いてドキュメントサイトを表示されます。
npm run doc
ドキュメントを見てみる
ではブラウザ上で、「あの感じ」で生成されたファイルを閲覧していきたいと思います。
サイトのルート
docs/index.html
はプロジェクトのドキュメントリンクと共に、依存パッケージのドキュメントも包含してくれます。
今回、user/projectという名前になっているのはelm-package.json
のrepository
のURLの記述のためです。
本来、githubのURLを入れるんですが、ウチはgitlabを使っているので、そのままにしています。
プロジェクトのルート
プロジェクト直下のREADME.mdの内容が表示されます。
右側のリンクでモジュールのドキュメントにアクセス出来ます。
モジュールページ
見慣れたページの感じになっています。これで社内Elmer達がお仕事をしやすくなってくれると嬉しい!
今回は以上でございます。
この仕組みが使いやすいのか否かはまだ検証フェーズで御座います(笑)。
それでは皆様、良いお年を!