Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
192 lines (121 sloc) 9.77 KB

執筆のために作成したツール

この書籍を書いている最中に開発した生成ツールやTravis CIと連携したテストについて。

HTML/Asciidoc

表示用JavaScriptの生成

書籍のサンプルコードは外部ファイルにしたかった。 しかし、そのまま読み込む使い方だと、サンプルコードのモジュール化が難しくなってしまった。 モジュール化が上手くできないとテストを書くことが難しくなる。 そこで、サンプルコード(src)と表示用コード(embed)にわけることにした。

そのために、サンプルコードから表示用コードを生成するモジュールを書いた。

Browserify等の既存のモジュールビルドツールでは require のエミュレートをするコードが入るため、 結合したコードがあまりキレイではない。

そこで作成したのが inlining-node-require でCommonJSのコードを見た目そのままに結合をすることができる。

Note

inlining-node-require は見た目はキレイに結合するが、 あらゆるパターンに対応することはできないため、ある程度の制限を持った書き方が必要になる。

サンプルコードは "use strict" を使ったコードとなっているが、 inlining-node-require で結合した際に重複することや表示用コードではスペース的に余計なものとなる。 remove-use-strict は不必要な "use strict" を取り除くことができるツール。

動作の詳細については下記の記事で紹介している。

サンプルコードの実行エディタ

Webで公開する書籍のメリットとして、その場でコードの実行結果が見られることが大きい。 書籍やウェブでの連載でもJSFiddle等のコード公開へのリンクを貼ったものが増えてきている。

そのため、サンプルコードがその場で実行できるのはメリットでありつつ、必要不可欠なものである。

日本語に対応したJavaScriptのコードエディタとしては CodeMirror が良くできているため、 CodeMirrorをベースにコードの実行機能を付加するモジュールを作成した。

codemirror-console はCodeMirrorに書かれているコードを実行できるモジュール。 単純にコードをevalするだけでは、グロールスコープを汚染してしまうため、 コードを実行する時にiframeを作り、その中でコードを実行している。

Nodeのvmモジュールと似た考え方をもつ context-evalを利用した。 これにより単純に実行するだけではなく、console を独自のものとすり替えて実行することができるようになっている。

codemirror-console-uicodemirror-consoleのUIを提供するモジュール。

codemirror-consoleは実行する機能のみであるため、UIは別モジュールとして作成した。

コンソールエディタの図

Testing

サンプルコードのテスト

サンプルコードはNode.js上で動くものとして作り、Node.jsで動くテストを書いた。

ES6 PromisesはDOMではなくECMAScriptの仕様であるため、 ブラウザが実行環境ではなくてもよいという考えと、実行の手軽さからNode.js上で動くものとして書いていった。

しかし一部を除いて、表示用コードはブラウザでの表示と実行を前提としている。 サンプルコードから表示用コードを自動的に生成しているが、 これはモジュールに関することのみを解決するため、サンプルコードはどちらの環境でも動く書き方が必要となった。

Node.js上でもブラウザと同様の機能がテストできるようにするためのPolyfillやモックが必要となった。 DOM APIが中心となり、具体的には XMLHttpRequestNotification 等が該当する。

XHR

Node.jsには XMLHttpRequest がないため、XMLHttpRequest と同じインターフェイスを持った HTTP通信ライブラリが必要となる。

この書籍では w3c-xmlhttprequest を使い、 Node.jsでも XMLHttpRequest と同じインターフェイスで通信をするコードを書くことができた。

Note

XMLHttpRequest と同じインターフェイスをNode.jsに提供するライブラリには以下のようなものがある。

どのライブラリも XMLHttpRequest の全ての機能が使えるわけではないため、 用途に合わせたものを選ぶ必要がある。

このライブラリをテスト実行前に、global に追加することで、 ブラウザとNode.jsで同様のコードを動かせるようにした。

global.XMLHttpRequest = require('w3c-xmlhttprequest').XMLHttpRequest;
Note

詳細は以下で紹介されている

Web Notifications API

テストできるようにすることが目的であるため、機能まで持ってくる必要性はなかった。 そのため、Web Notifications APIではNoticationのモックオブジェクトを作成し、テストを行った。

出力したHTMLのテスト

Asciidocでは [id] という記法で内部リンクを貼ることができるが、 この内部リンク先をリファクタリング時に変更してしまうことがあった。

そのため、生成したHTMLから内部リンクを取得して、移動先となる要素が 確かに存在するのかをテストするスクリプトを走らせている。

Asciidoc上のインラインコードテスト

この書籍中のコードには大きく分けて2種類ある。 ひとつは外部ファイルとして書いてテストも書いているサンプルコード。 もう一つは直接Asciidocのファイルに書いているインラインコードである。

外部ファイルのサンプルコードはテストしているため動作に問題ないことを保証できるが、 インラインコードは直接書くため実行して確認せず間違ったコードを書いてしまいがちだった。

そのため、Asciidocのファイルをパースして、インラインコードを抽出し、 そのコードが EsprimaといったJavaScriptパーサでパースできるかを検証できるようにした。

これによりJavaScriptの文法として間違っているものはパースエラーとなるため、 インラインに書いたコードのミスを検出するのに役立った。

Asciidoctorのビルドテスト

この書籍はAsciidoc形式で書き、asciidoctorによりビルドしている。

Asciidoctorではリソースが欠損しててもエラーではなくWARNINGとなるため、ビルドするときにWARNINGが発生したらCIが落ちるようにした。

Review

プレビュー

masterへマージされたものは、Travis CIで自動的にビルドして gh-pages ブランチにpushする。 これによりmasterへのコミットやpull-requestsをマージしたら自動的に https://azu.github.io/promises-book/ にて見られるようにしていた。

pull-requestsのコミットに対しては、そのコミットごとに preview-html ブランチに生成済みのHTMLがpushされる。

pushされた一時プレビュー用のURLをGitterに対して通知して、pull-request時のHTMLがプレビューできるようになっている。

preview-html.png

依存関係の可視化

セクション毎にテーマを分けてることが多いが、それを俯瞰的にどうやってみるかを模索するために、 セクション同士の依存関係を可視化するものを作成した。

You can’t perform that action at this time.