読者です 読者をやめる 読者になる 読者になる

ひだまりソケットは壊れない

ソフトウェア開発に関する話を書きます。 最近は主に Android アプリ、Windows アプリ (UWP アプリ)、Java 関係です。

まじめなことを書くつもりでやっています。 適当なことは 「一角獣は夜に啼く」 に書いています。

UWP アプリ開発に TypeScript + React を導入することの検討 (Node.MSBuild.Npm の紹介)

JavaScript TypeScript Visual Studio Windows Windows 10 WinJS ライブラリ 開発環境 UWP アプリ

こんにちは! 株式会社はてなにて、主に 「はてなブックマーク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 を使用するのが簡単でしょう。

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 ファイルとして使用するためには、webpackBrowerify などを使用してパックしてやる必要があります。 今回は私は 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 パッケージを作成し、公開しました。

www.nuget.org

使用方法は簡単です。 まず、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

おわりに

はてなでは、より開発しやすく、よりメンテナンスしやすいコードを記述していこうとするエンジニアを募集しています!

hatenacorp.jp

明日の 「はてなデベロッパアドベントカレンダー 2015」 の担当は id:motemen です。 お楽しみに!

*1:以下 UWP アプリ向けの話をしますが、Windows ストアアプリでも基本的に同様です。

*2:UWP アプリに限らず

*3:UWP アプリではないですが、大体一緒です。

*4:NuGet パッケージ内に node.exe や npm を含むようなタイプでも悪くはないのですが、exe ファイルを複数プロジェクトで共有したかったり、プロジェクトの階層が深い場所にあると npm のパッケージのインストールに失敗するという問題があったりするので、ビルド時にホームディレクトリにインストールしてくれるタイプのものが欲しいのでした。

*5:この文は 「はてなブックマークWindows ストアアプリの大幅な更新を予告するものではありません。