Promise本で取り組んだ電子書籍の開発ツール、CI、継続的リリースについて
Promise本の取り組み
JavaScript Promiseの本の開発で取り組んだ事と取り組んでおくべき(考慮しておくべき)だったことについてのメモ書き
技術書のディレクトリ構成とか参考になるものがあんまりなくて適当に作ったので、その辺を整理をしたい目的で書いてます。
はじめに
ここで書いたPromise本のディレクトリ構成やCI、テスト手法、使ったツールなどについては以下に大体書いてあります。
なので、結構省いて書いてるのでちゃんと見たい人は付録とかの方を見て下さい。
後、書籍の文章のフォーマットはAsciidocというOreillyが使っているものを使っていて、それのRuby実装であるAsciidoctorを使って書かれています。
多言語対応を考える
章毎に文章とソースコードとテストとリソースをディレクトリでまとめていた。
それをルート直下に配置していたため、多言語対応が取りにくい構成になってた。(実際、ディレクトリ浅くするためにこうしてたので、考えてなかった)
├── Appendix-Reference
│ └── readme.adoc
├── Ch0_Introduction
│ └── readme.adoc
├── Ch1_WhatsPromises
│ ├── embed
│ ├── img
│ ├── promise-overview.adoc
│ ├── readme.adoc
│ ├── src
│ ├── test
│ ├── what-is-promise.adoc
│ └── writing-promises.adoc
├── Ch2_HowToWrite
├── Ch3_Testing
├── Ch4_AdvancedPromises
書いた後に中国語の翻訳や韓国語の翻訳などもでてきたので、多言語対応を考えるまではいかないでも、以下みたいに一段ディレクトリを落としたほうが対応しやすいと思った。
docs/
├── Appendix-Reference
├── Ch0_Introduction
├── Ch1_WhatsPromises
├── Ch2_HowToWrite
├── Ch3_Testing
├── Ch4_AdvancedPromises
この辺は一般的な多言語に対応してるサイトの構成を参考にするのがいいのかと思った。
文章とソースコードとテストとリソースを章毎にディレクトリでまとめるという戦略自体は実際書きやすくなるので悪くないとは思ってるけど、他言語化すると重複するので分離するべきかは考える必要がありそう。
そもそもなんで章毎に全部リソースをまとめたかというと、プレビューのし易さを考えた時にそうなった。
Markedというプレビューするアプリを使っていて、以下のようなシェルスクリプトを作ってMarkedのCustom Markdown Processorのパスに指定して使っていた。
#!/bin/sh
~/.rbenv/shims/asciidoctor -a icons=font -a source-highlighter=coderay \
--backend html5 --base-dir "`dirname $MARKED_PATH`/" -
コードの多言語化
できなかったこと Asciidoc(Asciidoctor)では、// <1>
というコメントをコードに書いて、CodeBlockの外にその説明(<1> 説明文
)を書くという事ができる。
こういう参照ってどういう時に使うべきなんだろというのが曖昧だったけど、訳す必要があるところを外部に出すという意味で有用そうな気がする。
[source,javascript]
.Promiseを使った非同期処理の一例
----
// CodeBlock
var promise = getAsyncPromise("fileA.txt"); // <1>
promise.then(function(result){
// <2>
}).catch(function(error){
// <3>
});
----
<1> promiseオブジェクトを返す
<2> 取得成功の処理
<3> 取得失敗時の処理
[source,javascript]
.Promiseを使った非同期処理の一例
----
var promise = getAsyncPromise("fileA.txt"); // <1>
promise.then(function(result){
// 取得成功の処理
}).catch(function(error){
// 取得失敗時の処理
});
----
<1> promiseオブジェクトを返す
できたこと
JavaScript Promiseの本のサンプルコードはテストするために外部ファイルにしていて、Asciidocにファイルを読み込んで展開する機能があるのでそれを利用した。
----
include::embed/embed-promise-all-xhr.js[]
----
電子書籍のテストの種類
先ほどの被るけど、Promise本だとテストを4種類のテストをやっていた。 できたこと ●サンプルコードのテスト ●普通のコードのテスト ●出力したHTMLのテスト ●内部リンク切れがないかのチェック ●Asciidoc上のインラインコードテスト ●説明のために直接Asciidocに書いたコードの文法がおかしくないかのチェック ●Asciidoctorのビルドテスト ●Asciidoctorでビルドしているが、そのビルド時に警告があったらCIを落とすようにした できなかったこと ●用語統一チェックの自動化 ●promises-book/CONTRIBUTING.md at master · azu/promises-book ●表記の統一 · Issue #41 · azu/promises-book ●結局は目視チェックのみだった 今年のOSS活動振り返り @ 2014 | Web Scratchでも書いたけど、その後幾つかチェックツールを書いたので自動化できるんじゃないと思ってきたので次回やるならこれも行いたい。(Asciidocはパース難しそうなのでMarkdownとかがよさそう…) ●WEB+DB PRESS用語統一ルール等を使った技術用語のLintをするCodeMirrorアドオンを書いた | Web Scratch ●WEB+DB PRESS用語統一ルール(WZEditor)のパーサを書いた | Web Scratch ●JavaScriptでルールを書けるテキスト/Markdownの校正ツール textlint を作った | Web Scratch 後は文法チェックの自動化もRedPenとかでやりたかった(書いてる時まだなかった) 後、Google IME使うと普通にtypo多くなるのでATOKとか使ったほうが良さそうな気がしました。Asciidoc
Asciidoc(処理系としてAsciidoctorを使用)を初めて使って書きましたがこれは間違いではなかったと思います。 一番最初にTODOに上げた時はMarkdown + Leanpubで書きたいなーと思ってました。 ●Promisesの薄い本 · Issue #7 · azu/azu Markdownはインポート機能がないので、それをできるようにする拡張とかを書きながら色々考えましたが、結局はオレオレMarkdownになるだけでした。 ●pandocでMarkdownを拡張しコードをインポート出来るfilterを書く | Web Scratch 以前から気になってたAsciidoctorを触ってみたらデフォルトのHTML出力もいい感じだし、機能不足がなくてreStructuredTextほど複雑な書き方ではなかったので選択しました(Markdownにかなり近い書き方ができる)。 HTMLでの公開がメインでPDFはおまけな感じでしたが、調べたら日本語もフォント指定すればできると分かったので大丈夫でした。 ●[PDF/Epub] 出力形式について · Issue #2 · azu/promises-book Asciidoctorは無駄に多機能ですが、ドキュメントがよくできてるので大体そこを見れば解決するので良い感じでした。 ●Asciidoctor User Manual 一方、Markdownの方が馴染みあるので LeanpubのMarkdown処理系であるMarkuaの公開に期待しましょうという感じです。 またMarkdownの方がASTを吐いてくれるパーサ/ジェネレータとかあるのでツールを作りやすいとは思います。 まあ、Asciidocでも意外とpull requestされたので、そこまで複雑な使い方しないでガイドラインとか設ければどちらでもいい気がしました。 ●Contributors to azu/promises-bookIssueドリブンなワークフロー
できたこと Promise本はGitHub Issueを使ったワークフローになってます。 主に移動中に書いていたので、GitHub Issueにそのセクションの書きたい内容のアウトラインや検証結果をちょっとづつ書いていって、ある程度内容が固まったら書き出すというスタイルをとっていました。 なので、自分自身にPull Requestを送るスタイルでやっていて、実際の細かなワークフローについては以下のスライドに書いてあります。 ●一人で使えるGithub Issue できなかったこと Pull Requestに対するプレビュー環境がイマイチ上手くできてなかった。 現在もPull Requestされると自動でビルドしてprevi
ew-html
にpushすることで、それをrawgithub.com経由でHTMLがプレビュー出来るようになってます。
ただ、イマイチ感があるのでPull RequestごとにHerokuにデプロイしてプレビュー出来るようにしたい気がする。(masterへマージするとGitHub pagesにデプロイするのは自動化されています)
●GitHub Integration | Heroku Dev Center
公開後の更新
今年のOSS活動振り返り @ 2014 | Web Scratchにも書いてましたが、いまでも少しづつ更新しています。 こういう形態で書籍を公開したのは、常に書籍が更新出来るようにしたいからでもあります。 – JavaScript Promiseの本を書きました | Web Scratch 更新はモチベーションの問題も大きいですが、どれだけ簡単に更新できるかが大事な気がします。 ●CIによるテスト ●デプロイの自動化 は一応できてるので、GitHub上で直接編集するだけ更新出来るようになってます。その他
- Farata/EnterpriseWebBook
- Asciidocで書かれていて、実際にOreillyから出版されてる書籍(ソースが公開されてる)
- Eloquent JavaScript's Build System
- Eloquent JavaScriptもAsciidocで書かれていて、サンプルコードの実行エディタとか似てる部分があります。
- TypeScript in Definitelyland 発行
- Re:VIEWを使ったケース
お知らせ欄
JavaScript Primerの書籍版がAmazonで購入できます。
JavaScriptに関する最新情報は週一でJSer.infoを更新しています。
GitHub Sponsorsでの支援を募集しています。