M12i.

学術書・マンガ・アニメ・映画の消費活動とプログラミングについて

"Browserify Handbook"の翻訳をはじめた

f:id:m12i:20170715235343p:plain

Node.jsモジュールのブラウザ向けバンドル化ツールBrowserifyのドキュメント"Browserify Handbook"。このドキュメントはGitHubで公開されているのでForkした上で翻訳してみることにしました。まずまずの分量があるのでまあ段々とやっていこうかと思います。

はじめに

このドキュメントはモジュール化されたアプリケーションをビルドするためにbrowserify を利用する方法を説明したものです。

browserifyはNode.jsにより拡張された CommonJSモジュールをWebブラウザ向けにコンパイルするためのツールです。

もし仮にバンドル作成とnpmコマンドによるパッケージ・インストール以外では Node.js それ自体を利用していないとしても、あなたはあなたの製造したコードとサードパーティ製のライブラリ群を組み合わせるためにbrowserifyを利用することができます。

browserifyが利用するモジュール・システムはNode.jsが利用するそれと同じです。npm 向けに公開されたパッケージは、それが元来ブラウザのランタイムではなくNode.jsランタイムにおいて利用されることを想定して作成されたものであっても、browserifyによってブラウザ上でも同じように機能します。

多くの人びとがNode.jsランタイム上だけでなくbrowserifyを利用することでWebブラウザ上でも動作するよう設計されたモジュールをnpm向けに公開しつつあります。そしてnpmで公開されている多くのパッケージはまさにWebブラウザ上での利用を想定して設計されるようになってきています。 npm はすべてのJavaScriptランタイムのために利用できるものです。フロントエンドとバックエンドに大きなちがいはないのです。

目次

...

VSソリューションにDocFXのプロジェクトを追加する

.NETファミリー(.NET Framework、Mono、.NET Core)向けのドキュメント・ジェネレータの1つにDocFXがあります。このツール自体はVisual Studioやその他IDEからは独立したコマンドライン・ツールですが、Visual Studioソリューションの中でそのバイナリや設定ファイルを管理できると何かと便利そうです。というわけで、やってみました。

1. 下準備

まず今回の作業のためにサンプルのライブラリのソリューションを用意しました。もちろん実際にはここでドキュメント生成の対象とするソリューションをオープンするということになります:

f:id:m12i:20170708203415p:plain

あくまでサンプルなのでほとんど中身のないライブラリです。ダミーのクラス(public指定)とインターフェース(非public指定)だけです:

f:id:m12i:20170708203457p:plain

2. ドキュメント生成用のプロジェクトを追加

ソリューションに新しいプロジェクトを追加します。もっと良い方法があるのかもしれませんが、今回はクラスライブラリのプロジェクト・テンプレートを選択しました:

f:id:m12i:20170708203415p:plain

追加されたプロジェクトには自動でClass1.csなどのファイルが追加されますが、これらは不要なので削除します:

f:id:m12i:20170708203625p:plain

3. ドキュメント生成のための参照を追加

参照マネージャーを起動して(VS2017の場合、ソリューション・エクスプローラー内でドキュメント生成用プロジェクトの[参照]を右クリック→[参照の追加]をクリック)、ドキュメント生成の対象となるプロジェクトを選択します:

f:id:m12i:20170708204400p:plain

NuGetパッケージ・マネージャーを起動して(VS2017の場合、ソリューション・エクスプローラー内でドキュメント生成用プロジェクトの[参照]を右クリック→[NuGetパッケージの管理]をクリック)、"docfx.console"を検索してインストールします。インストールに際して提供者Microsoftのライセンスに同意を求められます:

f:id:m12i:20170708204543p:plain

4. DocFXの設定ファイルを編集しビルド

"docfx.console"のインストールが終わると一連の雛形ファイルがドキュメント生成用プロジェクトに追加されます。このなかの"docfx.json"をオープンして、コードを追加します:

f:id:m12i:20170708204736p:plain

JSONファイルのルート直下のプロパティ("metadata"とか"build"とか)はDocFXのコマンドライン・ツールを実行するときのサブコマンド名として認識されるもののようです。この中の"metadata"のセクションにある"src"プロパティ──"docfx metadata"コマンドで処理対象となるソースコードの定義情報──に, "src": "../(ドキュメント生成対象のプロジェクトのフォルダ名)"という一行を追加します。これでひとまず準備完了。

プロジェクトをビルドします(VS2017の場合、ソリューション・エクスプローラー内でドキュメント生成用プロジェクトを右クリック→[リビルド])。次のキャプチャ画像に示したような出力が行われます。すべて正常終了したことを確認します:

f:id:m12i:20170708205346p:plain

5. 生成されたドキュメントを確認

VS2017のソリューション・エクスプローラーには表示されませんが、プロジェクト・フォルダの直下に"_site"というフォルダがあり、そこに生成されたHTMLドキュメントが出力されています。"index.html"をIE Edgeで表示すると次のようにデフォルトのテンプレートでレンダリングされたドキュメントを閲覧できます:

f:id:m12i:20170708202426j:plain

"API Documentation"をクリックすると、ドキュメント生成対象のライブラリが公開しているメンバーの情報を閲覧できます:

f:id:m12i:20170708202510j:plain

なんとも残念なことにChromeブラウザで表示すると、XMLHttpRequestによるコンテンツのロードがクロス・オリジン・リクエストのエラーのため失敗しており、"toc.yml"で定義されている情報がロードできないために、各種ナビゲーションが無効になっています:

f:id:m12i:20170708202608j:plain

生成されたドキュメントを確認する方法としてはもう1つ、開発PC上でWebサーバを起動してそれ経由で配信されるコンテンツをWebブラウザで閲覧するというものがあります。この方法であれば上述のエラーは起きません:

> cd (プロジェクト・フォルダのパス)
> set PATH=..\packages\docfx.console.(NuGetでインストールしたバージョン)\tools;%PATH%
> docfx --serve

ショートファイル名で実行された場合でも*.exe.configを読み込む

前回の記事で紹介したように、Windows OSの環境で.NET Frameworkアプリケーションを実行するとき、エントリーポイントとなったアセンブリの名称がショートファイル名(8.3形式)で認識されるケースがあります。

この場合、アプリケーション構成ファイル *.exe.config は読み込まれず、ConfigurationManager.AppSettingsConfigurationManager.ConnectionStringsが返すコレクションは要素を含まない空のコレクションになってしまいます。

問題への対策にはConfigurationManager.OpenMappedExeConfiguration(...)メソッドを利用します:

string mayShortName = Assembly.GetEntryAssembly().Location;
string longName = Path.GetFullPath(mayShortName);
ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap
{
	ExeConfigFilename = longName  + ".config"
};
Configuration conf = ConfigurationManager.OpenMappedExeConfiguration
                    (fileMap, ConfigurationUserLevel.None);

このコードはPath.GetFullPath(...)メソッドがショートファイル名のパスをロングファイル名のパスに変換してくれるのを利用して、アプリケーション構成ファイルのパスを導出して読み込みを行います。

アプリケーション構成ファイルのロードには上位のファイルからの継承やローミングの有無など複雑な決まりごとがあるようで、それらすべてを考えた場合にこれが完全な対案となっているかどうかはわかりませんが・・・。

しかしAppSettingsプロパティなどが返すNameValueCollectionと異なり、このメソッドが返すのはConfigurationです。明らかに使い勝手が悪いです。ここからIDictionary<string, string>形式で設定情報を引き出すには次のようなコードを書くことになるでしょう:

IDictionary<string,string> appSettings = conf.AppSettings.Settings
                .Cast<KeyValueConfigurationElement>()
                .ToDictionary(e => e.Key, e => e.Value);
IDictionary<string,string> connStrings = conf.ConnectionStrings.ConnectionStrings
                .Cast<ConnectionStringSettings>()
                .ToDictionary(s => s.Name, s => s.ConnectionString);

やたらと手間がかかりますが、とにかくこれでアプリケーションがショートファイル名で実行された場合でも*.exe.configを読み込むことができます。