UWP アプリ開発に TypeScript + React を導入することの検討 (Node.MSBuild.Npm の紹介)
こんにちは! 株式会社はてなにて、主に 「はてなブックマーク」 Android アプリの開発を行っている id:nobuoka です。 この記事は、「はてなデベロッパーアドベントカレンダー 2015」 の 14 日目の記事です。 昨日は id:hatz48 による 「TypeScript だけで Web アプリケーションを作る」 でした。
今日は、昨日に引き続き TypeScript の話題となります。 主にクライアントサイド (特に UWP アプリ) での TypeScript と React の組み合わせについて検討したいと思います。
(この記事の内容は、UWP アプリへの導入を目的としたときの TypeScript + React の環境の一例であり、ベストプラクティスではありません。 より良い方法などがありましたら教えてくださいませ。)
UWP アプリと TypeScript + React
UWP アプリとは 「Universal Windows Platform アプリ」 のことで、Windows 10 で導入された Windows プラットフォーム向けのアプリの一種です。 Windows 8 で導入された Windows ストアアプリや Windows Phone 8.1 向けの Windows Phone アプリの進化版という感じですね。
現在のところ株式会社はてなでは UWP アプリの開発は行っていませんが、Windows ストアアプリ 「はてなブックマーク」 を 2012 年にリリースしています。 *1
JS を快適に書く : TypeScript の導入
Windows ストアアプリや Windows Phone アプリと同様に、UWP アプリも JS + HTML + CSS で開発することができます。 Windows ストアアプリ 「はてなブックマーク」 も JS + HTML + CSS の組み合わせで書かれています。
JS は Web 開発者にとって馴染みのある言語ですので、アプリ開発に取り掛かりやすいというのは利点ですね。 一方で、素の JS には変数に型がないためリファクタリングなどがしづらいという難があります *2。 それを解決するため、いわゆる Alt JS を使用することが検討されると思いますが、UWP アプリ開発で使用するのであればまず TypeScript が候補にあがるでしょう。 UWP アプリ開発に使用される統合開発環境 (IDE) Visual Studio 2015 では標準で TypeScript がサポートされているため、UWP アプリのプロジェクトに容易に TypeScript を導入できます。 Microsoft が TypeScript のリリースを行っているあたりも TypeScript 導入にあたっての安心感につながっています。 よほど TypeScript と比べて有利な言語があればそれを使うとよいかもしれませんが、私自身は現状では TypeScript を使うのが一番だと考えています。
実際に 「はてなブックマーク」 Windows ストアアプリ *3 でも TypeScript を導入して開発しており、素の JS を使うのに比べて楽に開発を進めることができています。
View の処理を快適にするために : React の導入を検討
TypeScript を導入することで JS の変数に型付けが行われて IDE のサポートを受けやすくなり、JS の世界については快適になります。 しかしながら TypeScript を導入するだけでは view 操作 (「何らかのデータを画面に表示する」 という処理) の部分はあまり改善されません。 UWP アプリ開発のための JS のライブラリとして WinJS というものがあり、画面にデータを表示するためのテンプレート・バインディングの機能が提供されているのですが、これがなかなか素朴な仕様で、型の恩恵を受けづらいためです。
「はてなブックマーク」 Windows ストアアプリの開発でも、やはり View を扱う部分がきれいに書けず、よりよい方法を取り入れたいと考えています。
そこで、何らかのライブラリを導入することを検討しました。 候補としては、以下のものを考えました。 いずれも JS 界隈で話題になりやすいライブラリですね。
- React
- JSX 構文を使って JS 側に HTML 構造を記述する。
- TypeScript との相性が良い。
- アプリ開発をするうえで扱いやすそう。
- Polymer
- 標準の Web Components を意識して開発されており、将来性はあるように見える。
- 独自の HTML タグを定義して HTML 側で使用できるので、(React と比べて) サーバーサイドで HTML を生成するような場面で扱いやすそう。
- TypeScript との相性は不明。
- AngularJS
- 現在 Angular 2 が開発されており、バージョン 1 と 2 の互換性がなくなりそうなことから、現在 Angular を導入するのはリスキーだと考えられる。
- View 部分を手軽に扱うためだけに導入するには規模が大きいように感じる。
全部試してみてどれが良いか評価できればよかったのですが、まずは TypeScript と相性がよく、アプリ開発で扱いやすそうな React だけを試してみました。
TypeScript と React (JSX) の相性
React では JSX 構文 (JSX syntax) を用いて JS の中に DOM 構造を記述します。 そして、TypeScript では JSX 構文がサポートされています。
JSX 構文での型チェックなどもサポートされているので、React を使うことで View の処理の部分でも IDE のサポートが受けられやすくなります。 プラグインなどではなく TypeScript の処理系に JSX 構文の処理が組み込まれているので、TypeScript と JSX の相性は非常に良いといえます。
TypeScript + React の環境
さて、ここからは実際に TypeScript + React を UWP アプリ開発で用いるための環境について考えます。 UWP アプリは、ローカルファイル上の HTML + JS + CSS をブラウザ上に表示するのと似たような仕組みで動きますので、まずはローカルファイルシステム上でビルドしてブラウザ上に表示できるようにする環境を考えます。
TypeScript + React の環境を整えるためには、npm を使用するのが簡単でしょう。
- TypeScript のビルド : npm の typescript モジュール
- React のソースコード : npm の react モジュール
- React の型定義 : npm の dtsm モジュールを使用して DefinitelyTyped から react.d.ts を取得
React を使うにあたっては CommonJS モジュールシステムを使うことが推奨されていますので、TypeScript を記述する際はモジュール形式で記述し、CommonJS 形式でコンパイルするようにしました。
We recommend using React with a CommonJS module system like browserify or webpack. Use the react and react-dom npm packages.
Getting Started | React
コンパイルした JS をブラウザ上で実行するために、また、UWP アプリの JS ファイルとして使用するためには、webpack や Browerify などを使用してパックしてやる必要があります。 今回は私は webpack を使用してみました。 (webpack を選択した理由は特にありません。 同僚からは、「webpack は大艦巨砲という感じなので、Browserify で事足りるなら Browserify で良さそう」 という意見をもらいました。)
これらのツールを使用して TypeScript + React のビルドを行うようにしたサンプルプロジェクトを GitHub で公開しています。 (ここではビルドシステムとして Gradle を使用しています。)
UWP アプリのプロジェクトへの TypeScript + React 開発環境の導入 : Node.MSBuild.Npm の紹介
さて、最後に UWP アプリのプロジェクトに上述の環境を構築することを考えましょう。
上で紹介した Gradle を使ったプロジェクトでは、Gradle から Node.js と npm を使用するために Gradle Plugin for Node を使用しています。 このプラグインは、ビルド時に Node.js と npm をダウンロードしてきて、セットアップしてくれるというものです。
一般的な UWP アプリのプロジェクトのビルドシステムである MSBuild でも同様の機能を使えれば、上で紹介したプロジェクトの Gradle 部分を MSBuild に置き換えることで、UWP アプリのプロジェクトに TypeScript + React の開発環境を導入できるでしょう。
MSBuild に似たような機能を提供する NuGet パッケージがないかどうか探したのですが、NuGet パッケージの中に node.exe や npm の各種ファイルを含むようなものは見つけられたものの、ビルド時にセットアップするタイプのものはなさそうでした *4。 そこで、そのような機能を持つ Node.MSBuild.Npm という NuGet パッケージを作成し、公開しました。
使用方法は簡単です。 まず、Visual Studio で NuGet パッケージマネージャを起動して 「Node.MSBuild.Npm」 を検索してインストールしてください。 あとは package.json を記述して、ビルド時に実行したい処理を build
スクリプトとして package.json に定義するだけです。
例えば、TypeScript + React 環境を構築してビルド時に TypeScript のビルドや webpack による変換を実行するには、以下のように記述します。
{ "name": "my-app", "private": true, "devDependencies": { "react": "^0.13.3", "webpack": "^1.12.9", "typescript": "^1.7.3", "dtsm": "^0.13.0" }, "scripts": { "build": "dtsm install & tsc -p ts --outDir built\\typescript & webpack" }, // 一部略 }
ビルド時に実行したい処理の記述方法に関しては、もう少し扱いやすいようにできると良いなぁと思っています。
ぜひご利用ください。
TypeScript + React 環境に対する評価
まだ軽く試している段階ですが、現時点での評価は以下のような感じで、個人的には他のライブラリ (Polymer や AngularJS) を試すまでもなく UWP アプリ開発に導入して良さそうという気がしています。
- (良い) TypeScript が JSX をサポートしているので、JSX 構文内でも IDE のサポートを受けやすくて記述しやすい。
- これは本当に便利です。
- (良い) React 自体は大きなフレームワークではなく、導入がしやすい。
- 画面内の一部の DOM 構造の構築のみに React を使用するなど。
- (良い) React により View のコンポーネント化ができ、開発しやすくなる。
- (良い) WinJS 側で React 用のアダプタが用意されており、WinJS と一緒に使いやすい。
- (微妙) TypeScript + React の環境を作るのが少し面倒。 慣れれば問題はなさそう。
- TypeScript をモジュールとして記述するかどうかや、モジュールとして記述する場合には browserify を使うか webpack を使うか、といったことで悩みそうです。 (React は CommonJS のモジュールシステムを使用することを推奨している。)
- (不明、問題なさそう) 将来にわたってメンテナンスしやすいかどうか。
- Facebook によりリリースされているので、ライブラリのメンテナンスの心配はそれほどなさそう。
- 使い方次第ではあるが、React を使いながら徐々に別のライブラリに移行するというのも難しくはなさそう。
「はてなブックマーク」 の Windows ストアアプリを更新する際には、こういった技術を導入することでより開発しやすく、メンテナンスしやすいコードを書けるようになりそうです。 *5
おわりに
はてなでは、より開発しやすく、よりメンテナンスしやすいコードを記述していこうとするエンジニアを募集しています!
明日の 「はてなデベロッパーアドベントカレンダー 2015」 の担当は id:motemen です。 お楽しみに!