<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:series="http://organizeseries.com/"
	>

<channel>
	<title>React &#8211; HTML5Experts.jp</title>
	<atom:link href="/tag/react/feed/" rel="self" type="application/rss+xml" />
	<link>https://html5experts.jp</link>
	<description>日本に、もっとエキスパートを。</description>
	<lastBuildDate>Sat, 07 Jul 2018 03:14:05 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.7.19</generator>
	<item>
		<title>React VRでここまでできる！VRでジオラマを作ろう</title>
		<link>/karad5/23960/</link>
		<pubDate>Mon, 31 Jul 2017 01:30:45 +0000</pubDate>
		<dc:creator><![CDATA[原一浩]]></dc:creator>
				<category><![CDATA[最新動向]]></category>
		<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[React]]></category>
		<category><![CDATA[React VR]]></category>
		<category><![CDATA[VR]]></category>

		<guid isPermaLink="false">/?p=23960</guid>
		<description><![CDATA[連載： React VR (4)前回、3Dプリミティブオブジェクトを使って、レイアウトやライティングの仕方について一通り試しました。前回扱わなかったコンポーネントに、3DモデルのためのコンポーネントModelがあります。...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/react-vr/" class="series-453" title="React VR" data-wpel-link="internal">React VR</a> (4)</div><div id="attachment_23961" style="width: 650px" class="wp-caption alignnone"><img src="/wp-content/uploads/2017/07/HelloDiorama-640x346.png" alt="" width="640" height="346" class="size-large wp-image-23961" srcset="/wp-content/uploads/2017/07/HelloDiorama.png 640w, /wp-content/uploads/2017/07/HelloDiorama-300x162.png 300w, /wp-content/uploads/2017/07/HelloDiorama-207x112.png 207w" sizes="(max-width: 640px) 100vw, 640px" /><p class="wp-caption-text">今回は、こんなVRジオラマをつくるぞ！</p></div>

<p>前回、3Dプリミティブオブジェクトを使って、レイアウトやライティングの仕方について一通り試しました。前回扱わなかったコンポーネントに、3Dモデルのためのコンポーネント<code>Model</code>があります。<code>Model</code>コンポーネントを使うと「obj」形式の3Dモデリングデータを読み込み、VR空間に配置することができます。</p>

<p>3Dのモデリングデータを使うと、リアルな物体だったり、複雑な形状を持ったオブジェクトを自由にVR上で扱えるため、VR空間における表現力が飛躍的に高まります。実際VRコンテンツを作る際に使うのは<code>Box</code>や<code>Cylinder</code>ではなく、<code>Model</code>コンポーネントになるでしょう。</p>

<p>今回は、3Dのモデリングデータを読み込み、ジオラマを作ってみましょう。子どもの頃、作ったプラモデルに顔を近づけて遊んだ経験はないでしょうか。VRでは、巨大な物体を目の前に表示させるのもお手のものです。</p>

<h2>新規プロジェクトの作成</h2>

<p>既に本連載の読者であれば何度か行ってきていることですが、今回もサンプルを作るにあたって新規プロジェクトを作成し、プロジェクトディレクトリへ移動します。<code>HelloDiorama</code>というプロジェクト名で進めることにします。</p>

<p></p><pre class="crayon-plain-tag">$ react-vr init HelloDiorama
$ cd HelloDiorama</pre><p></p>

<p>ジオラマに必要なものは何でしょうか? 一つは飾る対象物です。これはロボットなのかもしれないし、戦車かもしれないし、船かもしれません。3Dモデリングデータさえあれば、そしてそれをReact VRで読み込めさえすれば、なんでもジオラマにすることができます。</p>

<p>ちなみに「React VRで読み込めさえすれば」と書いているのは、Webで公開されている3Dモデリングデータの中には何故か表示できないものがあります。表示はできるけど変な形状になったりするものもあります。これはきっと時間と共に解決されていくタイプのものでしょう。気になることがあればReact VRのGitHubリポジトリでIssueを立てるとよいです。</p>

<p>続いてジオラマに必要なもう一つのものは何でしょう? それは雰囲気を与えてくれる背景です。緻密なモデルをさらに引き立ててくれる背景は、ロボットなら宇宙船の内部かもしれないし、船なら海上かもしれません。こちら背景は、今回は3Dプリミティブオブジェクトを利用してそれっぽいものを作ってみます。</p>

<h2>用意するもの</h2>

<p>ジオラマコンテンツを作るにあたって、用意するものは以下となりました。</p>

<ul>
<li>配置する対象物としての3Dモデリングデータ</li>
<li>背景の壁と床のテクスチャ</li>
</ul>

<p>まずは、配置する対象物としての3Dモデリングデータから用意しましょう。</p>

<div id="attachment_23962" style="width: 650px" class="wp-caption alignnone"><img src="/wp-content/uploads/2017/07/GAZ-AA-640x350.png" alt="" width="640" height="350" class="size-large wp-image-23962" srcset="/wp-content/uploads/2017/07/GAZ-AA.png 640w, /wp-content/uploads/2017/07/GAZ-AA-300x164.png 300w, /wp-content/uploads/2017/07/GAZ-AA-207x113.png 207w" sizes="(max-width: 640px) 100vw, 640px" /><p class="wp-caption-text">1930年代に使われたソ連製のトラックのモデルデータ</p></div>

<p>今回ジオラマとして、シーンに配置するのは、<a href="https://ja.wikipedia.org/wiki/GAZ-AA" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">GAZ-AA</a>という1930年代に使われたソ連製のトラックにしてみました。筆者は、このトラックを好きだったわけではないですが、様々な3Dモデルを探す中でふとこのトラックを見かけ、素朴な中にも車両全面に漂う気品を魅力に感じ、採用した次第です。</p>

<p>このトラックは、ポリゴン数が4,380と、そこそこ複雑な形状をしており、テクスチャなどを含んでいてなかなかにリアリティがあります。</p>

<p>下記より、objフォーマット形式のものをダウンロードしましょう。もし他の3Dデータで試す場合、ライセンスについてチェックしておきましょう。</p>

<ul>
<li><a href="https://www.cgtrader.com/free-3d-models/vehicle/truck/gaz-aa-furgon-bread" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">GAZ- AA furgon-Bread free VR / AR / low-poly 3D Model MAX OBJ 3DS FBX MTL</a></li>
</ul>

<p>ちなみに、上記ダウンロードサイトでは、ユーザー登録が必要です。なので、ほかのものを用意できる人は好きな3Dデータを利用してOKです。「gaz-aa_bread OBJ.zip」をダウンロード、解凍したら、下記のディレクトリにそれぞれ配置します。</p>

<ul>
<li>static_assets/gaz_aa/gaz-aa_bread.mtl</li>
<li>static_assets/gaz_aa/gaz-aa_bread.obj</li>
<li>static_assets/gaz_aa/gaz-aa_bread_cabin.jpg</li>
<li>static_assets/gaz_aa/gaz-aa_bread_detail.jpg</li>
<li>static_assets/gaz_aa/gaz-aa_bread_frame.jpg</li>
<li>static_assets/gaz_aa/gaz-aa_bread_furgon.jpg</li>
<li>static_assets/gaz_aa/gaz-aa_bread_wheel.jpg</li>
<li>static_assets/gaz_aa/gaz-aa_bread_wing.jpg</li>
</ul>

<p>上記ファイルのうち、実は「gaz-aa_bread.mtl」については変更する必要があります。</p>

<p>テキストエディタなどでファイルを開き、「D:\Program Files\Autodesk\3ds Max 2009\scenes\GAZ-AA free models\gaz-aa_bread_3ds_max&#42;<strong>.jpg」となっているところを「</strong>*.jpg」に書き換えましょう。これはきっと作ったときそのままのローカルのパスが入ってしまったのですね。公開する際の要注意ポイントと言えそうです。</p>

<p>ジオラマの背景に必要な素材は、角となる2面分の壁用のテクスチャと、床に使うテクスチャです。前回使った<code>Pano</code>コンポーネントで、6面にテクスチャを貼り、部屋状にしてしまうこともできますが、それだとリアルな空間になりすぎ、ジオラマっぽくなくなるからです。3面しか壁を用意しないことで、後ろには漆黒の空間が広がる感じになり、なんだか超現実的な世界になります。</p>

<div id="attachment_23963" style="width: 310px" class="wp-caption alignnone"><img src="/wp-content/uploads/2017/07/wall-300x169.jpg" alt="" width="300" height="169" class="size-medium wp-image-23963" srcset="/wp-content/uploads/2017/07/wall-300x169.jpg 300w, /wp-content/uploads/2017/07/wall.jpg 640w, /wp-content/uploads/2017/07/wall-207x116.jpg 207w" sizes="(max-width: 300px) 100vw, 300px" /><p class="wp-caption-text">背景の壁のテクスチャ</p></div>

<div id="attachment_23964" style="width: 310px" class="wp-caption alignnone"><img src="/wp-content/uploads/2017/07/floor-300x169.jpg" alt="" width="300" height="169" class="size-medium wp-image-23964" srcset="/wp-content/uploads/2017/07/floor-300x169.jpg 300w, /wp-content/uploads/2017/07/floor.jpg 640w, /wp-content/uploads/2017/07/floor-207x116.jpg 207w" sizes="(max-width: 300px) 100vw, 300px" /><p class="wp-caption-text">床のテクスチャ</p></div>

<p>壁と床のテクスチャは以下からダウンロードしてください。</p>

<ul>
<li><a href="https://html5experts.jp/wp-content/uploads/2017/07/diorama.zip" data-wpel-link="internal">diorama</a></li>
</ul>

<p>ちなみに、壁と床のテクスチャは、僕がそのへんで適当に撮ってきたものなので、フリーでお使いいただいて構いません。</p>

<p>ダウンロードしたら、「プロジェクトディレクトリ/static_assets/diorama」以下に「floor.jpg」と「wall.jpg」を配置しましょう。</p>

<h2>STEP 1. まずは、ジオラマのベースづくりから</h2>

<p>早速トラックを配置したいと、はやる気持ちを抑えてまずはジオラマのベースとなる背景の壁と床を作るところから始めましょう。床は、1000 x 1000の大きさを持った板を想定しました。これは、<code>Pano</code>コンポーネントで作った空間と同じ大きさとなります。そして、奥の壁は床から500の高さを持つ平面です。これにテクスチャをつけることで、リアリティを持たせます。では、具体的な作業をしましょう。</p>

<p>「index.vr.js」の<code>View</code>の中を一旦空にし、下記のように修正します。</p>

<p></p><pre class="crayon-plain-tag">&lt;View&gt;
              &lt;View
                      style={{
                        transform: [
                          {rotateY: -20},
                        ]
                      }}&gt;
                &lt;Plane
                        dimWidth={1000}
                        dimHeight={500}
                        style={{
                          transform: [
                            {translate: [-500, 220, 0]},
                            {rotateY: 90},
                          ],
                        }}
                        texture={asset('diorama/wall.jpg')}
                /&gt;
                &lt;Plane
                        dimWidth={1000}
                        dimHeight={500}
                        style={{
                          transform: [
                            {translate: [0, 220, -500]},
                          ],
                        }}
                        texture={asset('diorama/wall.jpg')}
                /&gt;
                &lt;Plane
                        dimWidth={1000}
                        dimHeight={1000}
                        style={{
                          transform: [
                            {translate: [0, -22, 0]},
                            {rotateX: -90},
                          ],
                        }}
                        texture={asset('diorama/floor.jpg')}
                /&gt;
              &lt;/View&gt;
            &lt;/View&gt;</pre><p></p>

<p>それと、importも変更しておきましょう。この先に使う<code>Model</code>コンポーネントやライティング関係のコンポーネントも加えておきます。</p>

<p></p><pre class="crayon-plain-tag">import {
  AppRegistry,
  asset,
  View,
  Plane,
  Model,
  DirectionalLight,
  PointLight,
  AmbientLight,
} from 'react-vr';</pre><p></p>

<p><code>View</code>コンポーネントが入れ子になっているのは、内側の<code>View</code>は、ジオラマの背景セットで、セット全体を変形させたい場合はこのように入れ子にしておくと、壁や床を一つの塊として扱えます。ここではジオラマのセット全体をちょっと回転させています。というのも、最初に表示したときに部屋の中央ではなく、部屋の角を見せたいためです。</p>

<p>ジオラマのセット自体を回転させずに、カメラを回転させるという表現方法もありますが、普通ジオラマというのは、インテリアの側面もあり、一番かっこいいポジションで飾るものだと思います。そこで、<code>View</code>自体をY軸に対して-20度回転させました。</p>

<p>さらに細部を見ていきましょう。3つの<code>Plane</code>が、内側の<code>View</code>コンポーネント内に配置されていますが、先頭2つの<code>Plane</code>コンポーネントは壁として配置してあります。位置を遠くに置いたのと、Y軸方向に90度回転させて垂直にそれぞれのコンポーネントが交わるようにしています。</p>

<p><code>Plane</code>コンポーネントに関わらず、3Dプリミティブコンポーネントは、テクスチャを設定することができます。テクスチャは<code>texture</code>属性で設定します。</p>

<p>ここでは<code>texture</code>属性に、「diorama/wall.jpg」を指定しました。これによりのっぺりとした壁が質感のある壁となりました。ちなみに、この壁は近くの公園の壁を撮影したものです。</p>

<p>一番最後の<code>Plane</code>は、床として配置しています。X軸方向に-90度回転させ、テクスチャを貼りました。これは海に行った時の砂岩の岩肌です。深い意味があるわけではないですが、オフロードっぽい印象になる写真が見つからなかったので、こちらを採用しました。</p>

<p></p><pre class="crayon-plain-tag">$ npm start</pre><p></p>

<p>を実行し、ブラウザでURLを開いてみましょう。ただし、こんどは「http://localhost:8081/vr/?hotreload」で開いてみてください。「?hotreload」を付けてブラウザから開くと、ホットリロードが可能になります。これで、エディタで編集したコンテンツが自動でブラウザ側に反映されるようになります。</p>

<div id="attachment_23966" style="width: 650px" class="wp-caption alignnone"><img src="/wp-content/uploads/2017/07/HelloDiorama_base-640x346.png" alt="" width="640" height="346" class="size-large wp-image-23966" srcset="/wp-content/uploads/2017/07/HelloDiorama_base.png 640w, /wp-content/uploads/2017/07/HelloDiorama_base-300x162.png 300w, /wp-content/uploads/2017/07/HelloDiorama_base-207x112.png 207w" sizes="(max-width: 640px) 100vw, 640px" /><p class="wp-caption-text">配置した背景</p></div>

<p>3方向のみ<code>Plane</code>を配置しただけの簡素なジオラマセットですが、VRで角のほうを見るとなかなかどうして迫力がありますね。</p>

<h2>STEP 2. 3Dモデリングデータを配置しよう!</h2>

<p>続いて、お待ちかねの3Dモデルの読み込みです。3Dモデリングデータの読み込みには、<code>Model</code>コンポーネントを使います。<code>Model</code>コンポーネントには、<code>source</code>属性を記述することができます。渡す内容は、<code>obj</code>と<code>mtl</code>というキーを持ったオブジェクトで、それぞれobj形式のファイルとmtl形式のファイルへのパスを渡します。</p>

<p>今回であれば、「配置するモデリングデータ」で保存しておいた「static_assets/gaz_aa」以下にあるobjファイルとmtlファイルが対象になります。</p>

<p><code>Model</code>コンポーネントは、「index.vr.js」の入れ子の内側の<code>View</code>以下に配置します。サイズは小さめにし、位置調整と<code>rotateY</code>プロパティを修正して、若干の回転を加えます。これは、ちょうど左前に向いた形がきれいだからです。コードは下記のようになります。</p>

<p></p><pre class="crayon-plain-tag">&lt;View&gt;
              &lt;View
                      style={{
                        transform: [
                          {rotateY: -20},
                        ]
                      }}&gt;
                &lt;Model
                        style={{
                          transform: [
                            {translate: [-30, -20, -110]},
                            {scale: 0.03},
                            {rotateY: 70},
                          ],
                        }}
                        source={{
                          obj: asset('gaz_aa/gaz-aa_bread.obj'),
                          mtl: asset('gaz_aa/gaz-aa_bread.mtl')
                        }}
                        lit={true}
                /&gt;
                &lt;Plane ... /&gt;
                &lt;Plane ... /&gt;
                &lt;Plane ... /&gt;
              &lt;/View&gt;
            &lt;/View&gt;</pre><p></p>

<p>これで、ブラウザをリロードしてみてください。3Dモデルが表示されるはずです。</p>

<div id="attachment_23967" style="width: 650px" class="wp-caption alignnone"><img src="/wp-content/uploads/2017/07/HelloDiorama_black-640x346.png" alt="" width="640" height="346" class="size-large wp-image-23967" srcset="/wp-content/uploads/2017/07/HelloDiorama_black.png 640w, /wp-content/uploads/2017/07/HelloDiorama_black-300x162.png 300w, /wp-content/uploads/2017/07/HelloDiorama_black-207x112.png 207w" sizes="(max-width: 640px) 100vw, 640px" /><p class="wp-caption-text">まだ光が当たっていないので真っ黒</p></div>

<p>ただし、真っ黒なシルエットになってしまっていますが。ということで、続いて光源を用意して、明るくしていきましょう。</p>

<h2>STEP 3. ライティングしてトラックを美しく!</h2>

<p>ライティングは、前回3Dプリミティブオブジェクトで遊んだ際に試したのを思い出してください。メインの明かり、部分的な明かり、ちょっとした調整です。今回も同じような感じで進めます。</p>

<p>実は、React VRで使われている3DライブラリのThree.js本体には、ライティングに関する様々なヘルパー機能が用意されています。例えば、照明の向き、範囲などを視覚的に表示して微調整をする機能などです。ただ、現時点のReact VRではもっと限定的なサポートとなっているのでそこまで細かくは扱いません。</p>

<p>「index.vr.js」に<code>DirectionalLight</code>と<code>PointLight</code>、<code>AmbientLight</code>コンポーネントを配置しました。これで、トラックが綺麗に表示されるでしょうか。</p>

<p></p><pre class="crayon-plain-tag">&lt;View&gt;
              &lt;DirectionalLight
                      intensity={0.3}
                      style={{
                        color: 'white',
                        transform: [
                          {translate: [0, 0, 0]},
                          {rotateX: 45}]
                      }}/&gt;
              &lt;PointLight
                      intensity={0.5}
                      style={{
                        color: 'white',
                        transform: [{translate: [50, 20, -80]}]
                      }}/&gt;
              &lt;AmbientLight
                      intensity={0.8}/&gt;
              &lt;View ... /&gt;
            &lt;/View&gt;</pre><p></p>

<div id="attachment_23968" style="width: 650px" class="wp-caption alignnone"><img src="/wp-content/uploads/2017/07/HelloDiorama_3d_model-640x346.png" alt="" width="640" height="346" class="size-large wp-image-23968" srcset="/wp-content/uploads/2017/07/HelloDiorama_3d_model.png 640w, /wp-content/uploads/2017/07/HelloDiorama_3d_model-300x162.png 300w, /wp-content/uploads/2017/07/HelloDiorama_3d_model-207x112.png 207w" sizes="(max-width: 640px) 100vw, 640px" /><p class="wp-caption-text">トラックがちゃんと表示された！</p></div>

<p>ブラウザをリロードしてトラックを再表示してみましょう。明るくなったでしょうか。</p>

<h2>STEP 4. トラックをゆっくりと回転させてみる</h2>

<p>以上で一旦はジオラマは完成しましたと言ってもいいかもしれません。ただ、今まで物体を空間に置いてみて歯がゆかったのは、その物体の裏側がどうなっているのか、それが見えないということでした。ということで、アニメーションの練習がてらトラックを回転させてみましょう。</p>

<p>回転に関しては、ピッタリのサンプルが公式のリポジトリに用意されています。</p>

<ul>
<li><a href="https://github.com/facebook/react-vr/tree/master/Examples/ModelSample" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">react&#45;vr/Examples/ModelSample at master · facebook/react&#45;vr</a></li>
</ul>

<p>このサンプルを参考にトラックのアニメーションを作ってみます。ちょっとサンプルと異なるのは、Reactのコンポーネントとして作るというのと、細かなロジックを修正した点です。Reactコンポーネントとして、回転速度を定義する<code>speed</code>属性と、表示位置や大きさを定義する<code>style</code>属性を渡せるように作っておきましょう。「src/component/GazAa.js」として下記のように作成します。ちょっと長くなるので、細部の話は置いておいて、まずは一気に掲載してしまいます。</p>

<p></p><pre class="crayon-plain-tag">import React from 'react';
import {
  asset,
  View,
  Model,
} from 'react-vr';

export default class GazAa extends React.Component {

  constructor() {
    super();
    this.state = {
      rotation: 0
    };
  }

  componentDidMount() {
    this.rotate();
  }

  componentWillUnmount() {
    if (this.frameHandle) {
      cancelAnimationFrame(this.frameHandle);
      this.frameHandle = null;
    }
  }

  rotate(timestamp) {
    const delta = timestamp - this.lastUpdate || 0;
    this.setState({rotation: this.state.rotation + delta / this.props.speed});
    this.lastUpdate  = timestamp;
    this.frameHandle = requestAnimationFrame(this.rotate.bind(this));
  }

  render() {
    return (&lt;View style={this.props.style}&gt;
              &lt;Model
                      style={{
                        transform: [
                          {rotateY: this.state.rotation},
                        ]
                      }}
                      source={{
                        obj: asset('gaz_aa/gaz-aa_bread.obj'),
                        mtl: asset('gaz_aa/gaz-aa_bread.mtl')
                      }}
                      lit={true}
              /&gt;
            &lt;/View&gt;
    )
  }
}</pre><p></p>

<p>ポイントは、<code>GazAa</code>コンポーネントのローカルステートとそれを変更するためのrotate関数、そしてそこで使われている<code>requestAnimationFrame</code>関数と<code>cancelAnimationFrame</code>関数です。</p>

<p><code>GazAa</code>コンポーネントは、シーンに配置した瞬間、つまりコンポーネントがマウントされた時から回転を始めます。逆にコンポーネントをアンマウントすると回転をやめる処理をします。回転の状態はコンポーネントのローカルステートとして定義されている<code>rotation</code>です。</p>

<p><code>rotation</code>は、3Dモデルの<code>rotateY</code>としてY軸方向にどれだけ回転するかという値として使われることになります。その値をコントロールしているのが<code>rotate</code>関数です。<code>requestAnimationFrame</code>関数は、ブラウザの再描画のタイミングで<code>rotate</code>関数を呼び出すことになるので、呼び出すたびに前に呼び出された時間からの回転を<code>rotation</code>に反映していきます。<code>requestAnimationFrame</code>関数から返った値は、アニメーションをキャンセルするときに<code>cancelAnimationFrame</code>関数にて使われます。</p>

<p><code>requestAnimationFrame</code>関数について一つ知っておきたいことは、この関数はもともとブラウザに実装されていますが、ブラウザによってはサポートされていないことがあります。そこで、React VRでは、<code>requestAnimationFrame</code>関数のpolyfillとして用意されています。</p>

<p>これで大体の<code>GazAa</code>コンポーネントの仕組みが理解できたでしょうか。今はこういうスタイルでアニメーションを実現したりしますが、将来的にはもっと洗練されたアニメーション機構が用意されていくのだろうと推測します。</p>

<p>では、先ほど作った<code>GazAa</code>コンポーネントを使っていきましょう。「index.vr.js」で使うので、まずはインポートします。ファイルの先頭あたりにimport文を書きます。</p>

<p></p><pre class="crayon-plain-tag">import GazAa from './src/component/GazAa'</pre><p></p>

<p>続いて、入れ子になった<code>View</code>コンポーネントの内側に、<code>GazAa</code>コンポーネントを配置します。プロパティとしては、回転速度を定義する<code>speed</code>属性と、表示位置や大きさを定義する<code>style</code>属性を渡しています。これら属性は、<code>GazAa</code>コンポーネント内の<code>this.props.XXX</code>にて受け取ることが可能です。これらを記載したコードが以下になります。</p>

<p></p><pre class="crayon-plain-tag">&lt;View&gt;
              &lt;DirectionalLight ... /&gt;
              &lt;PointLight ... /&gt;
              &lt;AmbientLight ... /&gt;
              &lt;View
                      style={{
                        transform: [
                          {rotateY: -20},
                        ]
                      }}&gt;
                {/* &lt;Model ... /&gt; */}
                &lt;GazAa speed={360}
                       style={{
                         transform: [
                           {translate: [-42, -20, -110]},
                           {scale: 0.03},
                         ],
                       }}/&gt;
                &lt;Plane ... /&gt;
                &lt;Plane ... /&gt;
                &lt;Plane ... /&gt;
              &lt;/View&gt;
            &lt;/View&gt;</pre><p></p>

<p>以上で、トラックが回転するジオラマの完成です。ブラウザをリロードして、じっくり見てみましょう！</p>

<div id="attachment_23961" style="width: 650px" class="wp-caption alignnone"><img src="/wp-content/uploads/2017/07/HelloDiorama-640x346.png" alt="" width="640" height="346" class="size-large wp-image-23961" srcset="/wp-content/uploads/2017/07/HelloDiorama.png 640w, /wp-content/uploads/2017/07/HelloDiorama-300x162.png 300w, /wp-content/uploads/2017/07/HelloDiorama-207x112.png 207w" sizes="(max-width: 640px) 100vw, 640px" /><p class="wp-caption-text">完成したVRジオラマ</p></div>

<p>もし興味があれば、<a href="https://html5experts.jp/karad5/23885/" data-wpel-link="internal">React VR×360度画像！Web上でパノラマVR表示を試す</a>を参考に、GearVRで眺めてみましょう。子供の頃叶わなかった、巨大サイズのジオラマを見ることができますよ。</p>
]]></content:encoded>
		
		<series:name><![CDATA[React VR]]></series:name>
	</item>
		<item>
		<title>React vs Angular 2ガチ対決！エキスパートたちによるハイレベル対談 (2 / 2) ー TechFeed Live#2レポート</title>
		<link>/shumpei-shiraishi/21754/</link>
		<pubDate>Tue, 13 Dec 2016 01:54:04 +0000</pubDate>
		<dc:creator><![CDATA[白石 俊平]]></dc:creator>
				<category><![CDATA[最新動向]]></category>
		<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[システム開発]]></category>
		<category><![CDATA[Angular 2]]></category>
		<category><![CDATA[React]]></category>

		<guid isPermaLink="false">/?p=21754</guid>
		<description><![CDATA[こんにちは、編集長の白石です。 本記事は、2016年9月に開催されたTechFeed Live#2 「React vs Angular 2」の模様をお伝えする記事の後編です（前編はこちら）。 TechFeed Live#...]]></description>
				<content:encoded><![CDATA[<p><style>
b.speaker {</p>

<p>}
b.speaker::after {
  content: ":";
}
</style>
こんにちは、編集長の白石です。</p>

<p>本記事は、2016年9月に開催された<a href="https://techfeed.connpass.com/event/38582/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">TechFeed Live#2 「React vs Angular 2」</a>の模様をお伝えする記事の<strong>後編</strong>です（前編は<a href="https://html5experts.jp/shumpei-shiraishi/21731/" data-wpel-link="internal">こちら</a>）。
TechFeed Live#2とは、「<a href="https://techfeed.io/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">TechFeed</a>を地上に出現させる」ことをコンセプトとした、テクノロジーの最新トレンドをエンジニア向けに紹介するというイベントです（TechFeedとは、「最先端が、ここにある。」をキャッチコピーとしたエンジニア向け情報収集アプリです）。本イベントは、ReactとAngularをより楽しく深く学ぶため、現代のWebアプリに求められる各種要件についてそれぞれを比較する…というアプローチを取りました。
（私は本イベントの企画と対談のモデレーターを務めました）</p>

<p>読み応えバッチリ、勉強になること間違いなし。今回はライブ感を重視し、あえてイベントでの（砕けた）口調も可能な限り再現してみました。
では皆様、どうぞお楽しみください！</p>

<div id="attachment_21783" style="width: 650px" class="wp-caption aligncenter"><img src="/wp-content/uploads/2016/12/IMG_2396.jpg" alt="TechFeed Live#2の模様" width="640" height="480" class="size-full wp-image-21783" srcset="/wp-content/uploads/2016/12/IMG_2396.jpg 640w, /wp-content/uploads/2016/12/IMG_2396-300x225.jpg 300w, /wp-content/uploads/2016/12/IMG_2396-207x155.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /><p class="wp-caption-text">かなりの熱気でした</p></div>

<h3>トークバトル参加者（順不同、敬称略）</h3>

<p>（編集部注: 本記事では登壇者の皆様の希望により、以下ハンドルネームで呼称させていただきます）</p>

<h4>React Side</h4>

<ul>
<li><b>koba04</b> (<a href="http://twitter.com/koba04" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">小林 徹</a>)</li>
<li><b>yosuke_furukawa</b> (<a href="http://twitter.com/yosuke_furukawa" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">古川 陽介</a>) (Node.js 日本ユーザグループ代表)</li>
</ul>

<div id="attachment_21758" style="width: 650px" class="wp-caption aligncenter"><img src="/wp-content/uploads/2016/12/IMG_2365.jpg" alt="Reactサイド" width="640" height="480" class="size-full wp-image-21758" srcset="/wp-content/uploads/2016/12/IMG_2365.jpg 640w, /wp-content/uploads/2016/12/IMG_2365-300x225.jpg 300w, /wp-content/uploads/2016/12/IMG_2365-207x155.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /><p class="wp-caption-text">Reactサイド。左がkoba04、右がyosuke_furukawa。</p></div>

<h4>Angular2 Side</h4>

<ul>
<li><b>laco</b> (<a href="http://twitter.com/laco0416" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">稲富 駿</a>) </li>
<li><b>83</b> (<a href="http://twitter.com/armorik83" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">奥野 賢太郎</a>) (ng-kyoto代表)</li>
</ul>

<div id="attachment_21759" style="width: 650px" class="wp-caption aligncenter"><img src="/wp-content/uploads/2016/12/IMG_2371.jpg" alt="Angular2サイド" width="640" height="480" class="size-full wp-image-21759" srcset="/wp-content/uploads/2016/12/IMG_2371.jpg 640w, /wp-content/uploads/2016/12/IMG_2371-300x225.jpg 300w, /wp-content/uploads/2016/12/IMG_2371-207x155.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /><p class="wp-caption-text">Angular2サイド。左がlaco、右が83</p></div>

<h4>モデレーター</h4>

<ul>
<li><b>shumpei</b> (<a href="http://twitter.com/Shumpei" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">白石 俊平</a>) (HTML5 Experts.jp編集長)</li>
</ul>

<p>また今回、フレームワークを比較するための項目を以下のように洗い出してみました。基本的にこの流れに沿って進めたいと思いますが、脱線は大歓迎ですので、皆様ご自由にご発言いただいて構いません。（編集部注: 後半は「スタイリング」から）</p>

<ul>
<li><s>開発⾔語</s></li>
<li><s>アーキテクチャ</s></li>
<li><s>ビルドツール</s></li>
<li><s>ルーティング</s></li>
<li><s>テンプレート</s></li>
<li>スタイリング</li>
<li>コンポーネント以外の処理</li>
<li>ツールサポート</li>
<li>テスト</li>
<li>パフォーマンス</li>
<li>サーバサイドレンダリング</li>
</ul>

<h2>スタイリング</h2>

<p><b class="speaker shumpei">shumpei</b> 次はスタイリングについてお話いただきたいと思います。コンポーネントにスタイルを当てる云々の話、ですね。
では、Reactサイドから伺いましょうか。ReactのCSSサポートの現状といったところからお聞かせ願えるとありがたいです。</p>

<p><b class="speaker yosuke_furukawa">yosuke_furukawa</b> CSS in JSとかそういったあたりの話ですね。CSSをJSの中にimportして、JavaScriptのオブジェクトかのように、コンポーネントにスタイルを当てることができる機能があります。
厳密なCSS in JSは、style属性に直接値をぶち込みます。そうすると、上からのCSSの影響を相当受けにくくできる。
そこまでいかなくても、CSS Modulesというのがあって、クラス名をuglify（難読化）してかぶらないようにして、中ではそのuglifyされたクラス名を使ってスタイリングを行い、外からの変更を受けにくくするというやり方もあります。</p>

<p>そういう感じで、CSSとJSを一体化して扱うということは、React界隈ではわりとやられています。</p>

<p><b class="speaker shumpei">shumpei</b> React本体はスタイリングとかに関する機能とかは持っていなくて、外のライブラリを使って実現するという感じなんですね。</p>

<p><b class="speaker koba04">koba04</b> はい、React本体としては、CSSは属性の一つ(style属性)なので、特別なサポートはそれほどありません。オブジェクトで値を指定できたり、幅や高さの単位を省略して指定できたりするくらいです。
あとはwebpackとかの外部のエコシステム上で、それぞれ好きにやっているという感じです。</p>

<p><b class="speaker shumpei">shumpei</b> では、Angular 2サイドはいかがでしょうか？</p>

<p><b class="speaker laco">laco</b> Angular 2は、<code>@Component</code>デコレータの中に<code>styles</code>という属性があって、そこに書いたスタイルはコンポーネントの中にしか効かないようになっています。Shadow DOMと同じ動きをするようにエミュレートされています。</p>

<p><b class="speaker yosuke_furukawa">yosuke_furukawa</b> どうやってエミュレートするんですか？</p>

<p><b class="speaker laco">laco</b> えーと、BEMみたいなのを自動的に生成します。それでかぶらないようにする。まあ、CSSをインポートすることはしないですが、文字列で指定してるので結局インポートしてるのとあまり変わらないというか…あんまり変わらないですね(笑)やりたいことは(Reactと)一緒です。</p>

<p>だけど違うのは、<strong>設定を一つ変えるとネイティブのShadow DOMを使えるように変えられます</strong>。現在のデフォルトはエミュレーションになってますが、将来的にShadow DOMに対応したブラウザが増えた時に、さくっと変えられるようにはなっていますね。</p>

<p><b class="speaker koba04">koba04</b> この辺 (スタイリング) は結構、開発メンバーの中にデザイナーさんがいるのかとか、JSがメインの人ばかりでやるのかとかで、どうCSS書くのかが変わってくると思うので、選択肢がいろいろあったほうがいいんじゃないかな、とは個人的には思っています。</p>

<h2>副作用を伴う処理</h2>

<p><b class="speaker shumpei">shumpei</b> では次に行きましょう。APIコールなど、副作用を伴う処理をどう扱うかは、フレームワークごとにかなりアプローチが異なってくるところだと思いますが、そこら辺の事情を伺わせてください。</p>

<p><b class="speaker laco">laco</b> まずAPIコールでいくと、Angular 2だとHttpというライブラリがあって、それを使うという話になります。</p>

<p><b class="speaker koba04">koba04</b> 今「ライブラリ」という言葉が出ましたが、(APIコールをするのに)外部のライブラリを使うという話なんですか？</p>

<p><b class="speaker laco">laco</b> npm的には別パッケージになってるんですが、Angular 2の一部という扱いです。サブパッケージと言ってもいいです。</p>

<p><b class="speaker koba04">koba04</b> そこをフレームワークが直接サポートする必要って何かあるんですか？</p>

<p><b class="speaker laco">laco</b> (Httpライブラリ内で) DIをガリガリ使っているというのと、Angularはフルスタックなフレームワークなので、アプリケーションを作るのに必要なものはとりあえず揃えておくというポリシーですね。</p>

<p><b class="speaker 83">83</b> あと、Angular 2のHttpをDIで使っておくとテストが楽、モックのAPI Callを自分でガリガリ書いたりする手間が省けるというのが利点かなと思います。</p>

<p><b class="speaker shumpei">shumpei</b> ちなみに個人的には、Reduxをちょっと調べた時にミドルウェアでAPIコールをしているのが「難しいな」と思ってしまったんですが、ああいうのは慣れれば全然問題なくなるもんなんでしょうか。</p>

<p><b class="speaker yosuke_furukawa">yosuke_furukawa</b> そこで難しいな、と思っちゃうのは<strong>まだReduxに慣れてない証拠</strong>です。</p>

<p><b class="speaker shumpei">shumpei</b> ほう。</p>

<p><b class="speaker yosuke_furukawa">yosuke_furukawa</b> Reduxっていうのは基本的に副作用をどんどん外していってるんです。APIからGETして取ってきたデータをステートに反映するというのは、これは副作用そのものなんです。
で、<strong>こういう副作用をどこでやるかと言ったらミドルウェアでやる、というのがReduxの基本的な考え方</strong>なんです。
そこに慣れると、みんなミドルウェアで書くっていうのがなんとなくわかる。そこに慣れてない人は、Reduxをフレームワークだと思って使っちゃうんです。</p>

<p><b class="speaker shumpei">shumpei</b> なるほど、基本的な思想がちゃんと理解できていなかったんですね、ぼくが。</p>

<p><b class="speaker yosuke_furukawa">yosuke_furukawa</b> あとReduxミドルウェアと言ってもいろいろあって、<a href="https://github.com/acdlite/redux-promise" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">redux-promise</a>だ、<a href="https://github.com/gaearon/redux-thunk" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">redux-thunk</a>だ、<a href="https://github.com/redux-observable/redux-observable" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">redux-observable</a>だ、<a href="https://github.com/yelouafi/redux-saga" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">redux-saga</a>だと、ぼくは<a href="https://github.com/redux-effects/redux-effects" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">redux-effects</a>っていうのを使ってるんですけど。
要は、副作用が必要なときに副作用を発生させる方法っていうのはたくさんあるし、非同期の処理の仕方一つ取ってもたくさんあるわけです。
ES6のジェネレーターでやるっていうのがredux-sagaだし、そうじゃなくてPromiseでいいんじゃないの、っていう人はredux-thunkだとかredux-promiseだとかを使う。</p>

<p>そうじゃなくてもうちょっと高次元なことをしたい、複数のイベントを包括的に扱ったりしたいという場合はObservableが必要になってくる、と。
それはどこまでデカい規模のものを作るかによってミドルウェアの選定をしなくてはならなくて、そこをツライと言ってしまうとちょっと(Reduxを使うのは) 厳しいかもしれません。</p>

<p>フレームワークなのかライブラリなのかという話でいくと、昔あったAngularJSのMVWhateverだったりなんだったりっていうものをReduxの何かで置き換えられるかというと、あんまりそんなことやってくれないんですよね。
結構薄いライブラリなので。フレームワークじゃないとぼくがずっと言っているのはそういうことです。</p>

<p>何かおまかせできるわけじゃなくて、自分たちでシンプルなAPIをたくさん作って、やってくれるのは状態の管理とイベントの管理だけ、というのがReduxの思想というか。
で、副作用を徹底的に省いてくれる。</p>

<p>でもみんな気になってるのは、その副作用をどうやってやるの、というところで、フレームワークを使いたいと思っている人にとってはそこにミスマッチがあるんじゃないかと思っています。</p>

<h2>テスティング</h2>

<p><b class="speaker shumpei">shumpei</b> では、テスティングについてはいかがでしょう？</p>

<p><b class="speaker yosuke_furukawa">yosuke_furukawa</b> コンポーネントのテスト書くか書かないか、って話があるんですが。書くか書かないかをまずはお聞きしたい。
書くとすると、こちらは<a href="https://github.com/airbnb/enzyme" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">enzyme</a>っていうツールを使ってます。</p>

<p><b class="speaker laco">laco</b> こっちは<a href="https://karma-runner.github.io/1.0/index.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Karma</a>っていうのを使います。KarmaはAngularチームが作っているテストフレームワークです。なので、KarmaがAngularと一番相性のいいテストフレームワークとして使ってますね。</p>

<p>あと、Angularがテスティング用のAPIを内包しているおかげで、コンポーネント単位でのテストができるようになってます。
たぶんenzymeとそんなに変わらないと思います。</p>

<p><b class="speaker koba04">koba04</b> そうですね、enzymeはいろいろラップしていて、DOMにマウントしたコンポーネントに対するテストとか、<code>renderToString()</code>で書き出したHTML文字列に対するテストとか、対象のComponentだけを浅くrenderする<code>ShallowRenderer</code>などを提供しています。</p>

<p>そういうのを提供するために、ReactはTestUtilsというアドオンを提供しています。最近だとTestRendererっていう、ツリー構造をただのJSONで返してくれて、それに対してテストするみたいなのもあります。なので、テストは書きやすいかな。
あと、Reactのコンポーネントって多くはただの関数で、状態を持たない。入力を与えたら、React Elementのオブジェクトが返ってくるというただの関数なので、テストも簡単に書けるという感じです。</p>

<p>Reduxとか使うと、そのただの関数の部分がReducerだったりと増えてくるので、より簡単に書けるとは思います。
あとShallowRendererだったらDOMにも依存しないので、JSDOMなどを使う必要ないし、NodeとかでMochaとかPower Assertとか使って簡単にすぐかけるというのはいいところかなあと思います。</p>

<p><b class="speaker laco">laco</b> 書くか書かないか問題で行くと、<strong>Angular 2の場合は書かないとまずい</strong>んですよね。テンプレートが間違ってた時に本番でぶっ壊れるので、テンプレートがコンパイル可能かというのを、コード生成可能なテンプレートになっているかというのをテストしないとまずくて。JSXの場合はコンパイルエラーになってくれるけど、Angular 2のテンプレートはただの文字列なので、実行するまでわからないというのがあって。</p>

<p><b class="speaker yosuke_furukawa">yosuke_furukawa</b> ただ、そもそもビューのところって変更が一番多いところだと思うんです。そこってテスト書いちゃうと、ROI (投資対効果) 的にというか、コストがペイしないんじゃないかとぼくは思っていて。なので、基本は「書かない」がいいんじゃないかと思ってます。</p>

<p><b class="speaker laco">laco</b> コンポーネントの中のプロパティのテストとかですか？</p>

<p><b class="speaker yosuke_furukawa">yosuke_furukawa</b> そう、それとか…。</p>

<p><b class="speaker laco">laco</b> だったら、基本やんないですね、あんまり。</p>

<p><b class="speaker yosuke_furukawa">yosuke_furukawa</b> lacoさんの言っているテストっていうのは、テンプレートがコンパイル可能かどうかの(最低限の)テストってことですか。</p>

<p><b class="speaker laco">laco</b> そう、それは全コンポーネント通しておかないと夜も眠れない(笑)。</p>

<p><b class="speaker yosuke_furukawa">yosuke_furukawa</b> それは、たしかに(Reactは)JSXはコンパイル時にわかる。</p>

<p><b class="speaker laco">laco</b> それに、一口でコンポーネントっていいますが、そっちは関数ですが、こっちはステートを持つやつなんで、性質が全く違います。</p>

<p><b class="speaker shumpei">shumpei</b> AngularのほうはDIでテスタビリティを向上させている。一方でReactにはDIとかそういうのはないけど、Reactのコンポーネントはただの関数なことが多いからテストしやすいと。</p>

<p><b class="speaker yosuke_furukawa">yosuke_furukawa</b> Reactのコンポーネントは基本的にステートを持たないから、そこ（DIとか）に関心がない。性質の違いですね。</p>

<h2>パフォーマンス</h2>

<p><b class="speaker shumpei">shumpei</b> 次はパフォーマンスです。これって議論になるのかな？</p>

<p><b class="speaker laco">laco</b> 今はもう、あんまり(どちらのフレームワークのパフォーマンスも)変わらないですよね。Angularのほうが初期ロードはちょっと遅いかもしれないけど、動き始めてからはあんまり変わらない。</p>

<p><b class="speaker 83">83</b> これ、AngularJSでアプリ作ってて、Angular 2でもアプリ作ってて、って経験から言うと、AngularJSだから遅い、ってAngularのせいにできたんですよね。「ここ遅いのなんで？」って言われた時にAngularJSのせいです、って言っちゃえるという甘えがあったんですけど。</p>

<p>最近Angular 2とReactほとんど差がないんで、自分の書いてるコードが酷い可能性のほうが高い。自分の書いたコードを疑えって言う。最近パフォーマンスというか、自分がどれだけ最適化されたコードを書けるかとか、遅かった時にどう測定してどこを最適化していくか、っていうところにかかってるんじゃないかなと思います。</p>

<p><b class="speaker laco">laco</b> (Reactは)たぶん、ミドルウェア書けば書くほど遅くなりますよね。Angularも、いろいろやればやるほど遅くなる。DOMの書き換えパフォーマンスはどちらも変わらないと思います。</p>

<p><b class="speaker yosuke_furukawa">yosuke_furukawa</b> ただ、DOMの書き換え周りって、仮想DOMとか変更検知のアルゴリズムとかも関わってくる話ですよね。変更検知については、Angular1の頃は、自分でイベントループみたいの持っててそこでダーティチェックしてたけど、2はどうなってるんですか？</p>

<p><b class="speaker laco">laco</b> Zone(.js)の話になるんですけど…Zoneの話長いんで(笑)。
ざっくりいうと、<strong>windowをモンキーパッチ</strong>して、</p>

<p><b class="speaker yosuke_furukawa">yosuke_furukawa</b> モンキーパッチ！？(笑)</p>

<p><b class="speaker laco">laco</b> setTimeout()とかXHRとか非同期イベントが起きた後は必ずAngularのイベント呼ぶようになってる。</p>

<p><b class="speaker yosuke_furukawa">yosuke_furukawa</b> マジかよ…<strong>めちゃEvilじゃないか…！</strong>(笑)</p>

<p><b class="speaker laco">laco</b> でもそれがTC39にZoneとして提案されていて、すでに（ステージ）0にもなってるんですよ(笑)。 (編集部注: ECMAScriptの仕様策定は、アイデアレベルの提案がステージ0に始まり、成熟するに従ってステージを登っていく）</p>

<p>だから…あれ、何の話だっけ。ああそうか、変更検知のイベントループの話だ。(Angular)1の頃はループガンガン回してたけど、それはもうないです。何も起きてないときは何も動かない。何かしらクリックしたとかがあったら、イベントが走って、windowからAngularにお知らせが来る、というふうになってるんです。</p>

<p><b class="speaker koba04">koba04</b> パフォーマンスっていう意味で言うと、Reactは基本やることが少ないし、やることが明確なので、チューニングはしやすいのかなあと思います。
<a href="https://www.npmjs.com/package/react-addons-perf" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">react-addons-perf</a>とか使って計測して、パフォーマンスチューニングのポイントも<code>shouldComponentUpdate</code>を実装するか、renderの中をちょっと見直すとかなので。</p>

<p><b class="speaker laco">laco</b> しかし、仮想DOMは速かったけど、Angularも追いついちゃいましたね。<strong>しかも仮想DOMなしで</strong>。結局仮想DOMってどうだったのかなあ…と。「ポイント、そこじゃなくない？」っていう(笑)。 (筆者注: ここ、lacoさんがイベントを盛り上げるため煽ってくれてます)</p>

<p><b class="speaker koba04">koba04</b> まあ、仮想DOMだからこそ、ただの関数みたいな形でコンポーネントを簡単に作れるようになったので…。</p>

<p><b class="speaker laco">laco</b> でも、最近<a href="https://facebook.github.io/react/docs/pure-render-mixin.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Pure Component</a>って入ったじゃないですか。Shallow Rendererとか。
あれってどうなんですか？この間ものすごく疑問に思って。Pure Componentにすると、オブジェクトの状態を自動で見て、自動で変更検知してくれるってやつですよね。
<strong>あれって、Reactがやりたかったことなんですか？</strong></p>

<p><b class="speaker koba04">koba04</b> あれは、オブジェクトツリーがでかくなると仮想DOM比較のコストもバカにならないので、その比較すらも飛ばしたい時に使うっていう感じです。</p>

<p><b class="speaker laco">laco</b> 仮想DOMのアルゴリズムが敗北したってことじゃないですか？(笑)</p>

<p><b class="speaker shumpei">shumpei</b> 煽る煽る(笑)。</p>

<p><b class="speaker koba04">koba04</b> 基本的にはそこまで必要とするものでもなくて、よっぽどパフォーマンスが求められる場面で使われるものかなと思っています。</p>

<p><b class="speaker yosuke_furukawa">yosuke_furukawa</b> ぼくとしては、パフォーマンスのチューニングポイントが増えたって話だと思ってます。<strong>仮想DOMの敗北については、次のサーバーサイドレンダリングでぼくが話をする</strong>んで、まあここはこれくらいでいいんじゃないかなと(笑)。</p>

<p><b class="audience">会場</b> (笑)</p>

<h2>サーバーサイドレンダリング</h2>

<p><b class="speaker shumpei">shumpei</b> じゃあ、サーバーサイドレンダリング(SSR)について、yosuke_furukawaさんどうぞ(笑)。</p>

<p><b class="speaker yosuke_furukawa">yosuke_furukawa</b> そうですね、実際にSSRでもコンポーネントのツリー構造を作って、そのツリーに対してReact DOMのIDを割り振るっていうような「仮想DOMを構築する処理」が入るわけなんですが、それって<strong>普通のテンプレートエンジンだとまずやらない処理</strong>なんですよね。普通のテンプレートエンジンはHTML生成すればいいだけだから。効率化されているんです。</p>

<p>そこをReactのrenderToString()とかでやると、まあ、そこまで効率化されていない。
もしかしたらキャッシュとか持って、効率化する余地はあるのかもしれないんだけど、今のReactだとそこまで効率化されていないので、やっぱりテンプレートエンジンとしてのスピードを見るとそこまで速くないんです。
そこがちょっとね、どうしたもんかね、と。</p>

<p>ぼくが今やってるやつだと、1レンダリングするのに50ミリ秒とかかかっちゃって、しかも50msecかかった時に、<strong>Node.jsなんでイベントループが止まっちゃってる</strong>んですよね。だから由々しき問題、由々しき事態なんです。
だからそこは、非同期処理にしてイベントループを止めないようにするか、キャッシュですごい速くするか、そもそもDOMツリーを構築するところをなんとかするかと言ったことが必要なんですけど。</p>

<p><b class="speaker koba04">koba04</b> そういう意味では、Reactってサーバーサイドレンダリングできるんですけど、正直あれなんで入ってるのかぼくはよくわかってなくて(笑)。Facebook自身も使ってないですしね。
中のアルゴリズムを見ると、クライアントのDOMを作るときと同じコードを使っているので、それは当然文字列作るのと比べれば効率悪い。
そこはもしかしたら新しいアルゴリズムが入ることで効率化するのかもしれないけど、たしかに今だとパフォーマンスが問題になるのは明白な感じの実装にはなってます。</p>

<p><b class="speaker yosuke_furukawa">yosuke_furukawa</b> Netflixとか、いろんな企業が実際にサーバサイドレンダリングはやってるんですけど、初期表示のレンダリングするところだけサーバサイドレンダリングして、
あとはスクロールするたびにちょっとずつクライアントサイドレンダリングしてたりする。<strong>それって地獄じゃねえのか</strong>、と(笑)。
そういうことが簡単にできるライブラリとかが別途あればいいんだけど、今のところまだないから、そういう意味だと、仮想DOMは敗北に近いかなと。サーバサイドレンダリングするなら。</p>

<p><b class="speaker shumpei">shumpei</b> Angular 2のサーバサイドレンダリング事情はどうですか？</p>

<p><b class="speaker laco">laco</b> Angularのサーバサイドレンダリングは…たぶんあんまり変わらないですよ。基本的に遅い。ただ何がいいかって、ルーティングとかHttpとか、Node上でも動くように全部パックされてるという、フルスタックならではの安心感はありますね。</p>

<p>ルーティングが済んだ状態のSSRも簡単にできるし、SSRするときに最初にAjaxが必要だったら、Node上で動く@angular/httpみたいな、ユニバーサルなやつが提供されている。それを使えば、変更検知された状態のSSRがちゃんと出ます。全部レールに乗ってるっていう、そこらへんの安心感はありますね。</p>

<h2>ライブラリか、フレームワークか</h2>

<p><b class="speaker shumpei">shumpei</b> はいでは、お時間も迫ってまいりましたので、そろそろ終わりにしたいと思います。</p>

<p><b class="speaker 83">83</b> あ、一ついいですか？<strong>ちょっとこのイベント自体に苦言を呈したくて。</strong></p>

<p><b class="audience">会場</b> (笑)</p>

<p><b class="speaker shumpei">shumpei</b> え、なんでしょう？</p>

<p><b class="speaker 83">83</b> ReactとAngularっていうのを比べるのって、みんな大好きですよね。でも、ほんとはこれって比較できるもんじゃないんですよ。型が一致しないものは比較できないんですよ。</p>

<p><b class="audience">会場</b> (笑)</p>

<p><b class="speaker 83">83</b> で、比較できないものを比較しているというのは、こういう項目を挙げてやっているっていうのは、フレームワークの相互プレゼンテーションみたいな感じで、Reactはこうですよ、Angular 2はこうですよ、という感じでやってるんですけど、ほんとにそれがみんな聞きたい話なのか？って思うんです。</p>

<p>私はlacoのほうからオファーを受けて呼んでもらったんですけど、こんだけすごいパネラーが揃ってて、順番にフレームワーク・ライブラリ紹介合戦みたいになってて。これじゃないでしょ、って思ってるんですよね。
もっと、フロントエンドのエンジニアとして、Web APIがどういうものがあって、いつ何を使うか、どう組み合わせるかっていうのがやっていくべきことなのに、何年かしたらすぐ廃れるようなライブラリの議論なんてのに、似非プロレスなんてのをやっていても、これは違うんじゃないかなあ、と思うんですよね。</p>

<p><b class="speaker shumpei">shumpei</b> すいません、、反省します。</p>

<p><b class="speaker 83">83</b> いえいえ、これ、言っとかないと終わってしまうな、と。すいません。</p>

<p><b class="speaker yosuke_furukawa">yosuke_furukawa</b> いえいえ…最高です(笑)。</p>

<p><strong><a href="https://html5experts.jp/shumpei-shiraishi/21754/" data-wpel-link="internal">前編もあります</a></strong></p>
]]></content:encoded>
			</item>
		<item>
		<title>React vs Angular 2ガチ対決！エキスパートたちによるハイレベル対談 (1 / 2) ー TechFeed Live#2レポート</title>
		<link>/shumpei-shiraishi/21731/</link>
		<pubDate>Tue, 13 Dec 2016 01:39:21 +0000</pubDate>
		<dc:creator><![CDATA[白石 俊平]]></dc:creator>
				<category><![CDATA[最新動向]]></category>
		<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[システム開発]]></category>
		<category><![CDATA[Angular 2]]></category>
		<category><![CDATA[AngularJS]]></category>
		<category><![CDATA[React]]></category>

		<guid isPermaLink="false">/?p=21731</guid>
		<description><![CDATA[こんにちは、編集長の白石です。 本記事は、2016年9月に開催されたTechFeed Live#2 「React vs Angular 2」の模様をお伝えする記事の前編です（後編はこちら）。 TechFeed Live#...]]></description>
				<content:encoded><![CDATA[<p><style>
b.speaker {</p>

<p>}
b.speaker::after {
  content: ":";
}
</style></p>

<p>こんにちは、編集長の白石です。</p>

<p>本記事は、2016年9月に開催された<a href="https://techfeed.connpass.com/event/38582/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">TechFeed Live#2 「React vs Angular 2」</a>の模様をお伝えする記事の<strong>前編</strong>です（後編は<a href="https://html5experts.jp/shumpei-shiraishi/21754/" data-wpel-link="internal">こちら</a>）。
TechFeed Live#2とは、「<a href="https://techfeed.io/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">TechFeed</a>を地上に出現させる」ことをコンセプトとした、テクノロジーの最新トレンドをエンジニア向けに紹介するというイベントです（TechFeedとは、「最先端が、ここにある。」をキャッチコピーとしたエンジニア向け情報収集アプリです）。本イベントは、ReactとAngularをより楽しく深く学ぶため、現代のWebアプリに求められる各種要件についてそれぞれを比較する…というアプローチを取りました。
（私は本イベントの企画と対談のモデレーターを務めました）</p>

<p>読み応えバッチリ、勉強になること間違いなし。今回はライブ感を重視し、あえてイベントでの（砕けた）口調も可能な限り再現してみました。
では皆様、どうぞお楽しみください！</p>

<div id="attachment_21762" style="width: 650px" class="wp-caption aligncenter"><img src="/wp-content/uploads/2016/12/IMG_2373.jpg" alt="TechFeed Live#2の模様" width="640" height="480" class="size-full wp-image-21762" srcset="/wp-content/uploads/2016/12/IMG_2373.jpg 640w, /wp-content/uploads/2016/12/IMG_2373-300x225.jpg 300w, /wp-content/uploads/2016/12/IMG_2373-207x155.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /><p class="wp-caption-text">当日のイベントは大盛り上がりでした。</p></div>

<h2>React vs Angular 2対決開始！</h2>

<p><b class="speaker shumpei">shumpei</b> 本日は、多くのお客様にご参加いただいて、大変うれしく思います。
今回のTechFeed Liveは、「React vs Angular 2」と題しまして、今をときめくコンポーネント指向のWebアプリケーション・フレームワーク2つを比較して学べる会を目指しています。</p>

<p>そのために、それぞれのフレームワークのエキスパートの方々にお集まりいただきました。</p>

<h3>トークバトル参加者（順不同、敬称略）</h3>

<p>（編集部注: 本記事では登壇者の皆様の希望により、以下ハンドルネームで呼称させていただきます）</p>

<h4>React Side</h4>

<ul>
<li><b>koba04</b> (<a href="http://twitter.com/koba04" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">小林 徹</a>)</li>
<li><b>yosuke_furukawa</b> (<a href="http://twitter.com/yosuke_furukawa" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">古川 陽介</a>) (Node.js 日本ユーザグループ代表)</li>
</ul>

<div id="attachment_21758" style="width: 650px" class="wp-caption aligncenter"><img src="/wp-content/uploads/2016/12/IMG_2365.jpg" alt="Reactサイド" width="640" height="480" class="size-full wp-image-21758" srcset="/wp-content/uploads/2016/12/IMG_2365.jpg 640w, /wp-content/uploads/2016/12/IMG_2365-300x225.jpg 300w, /wp-content/uploads/2016/12/IMG_2365-207x155.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /><p class="wp-caption-text">Reactサイド。左がkoba04、右がyosuke_furukawa。</p></div>

<h4>Angular2 Side</h4>

<ul>
<li><b>laco</b> (<a href="http://twitter.com/laco0416" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">稲富 駿</a>) </li>
<li><b>83</b> (<a href="http://twitter.com/armorik83" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">奥野 賢太郎</a>) (ng-kyoto代表)</li>
</ul>

<div id="attachment_21759" style="width: 650px" class="wp-caption aligncenter"><img src="/wp-content/uploads/2016/12/IMG_2371.jpg" alt="Angular2サイド" width="640" height="480" class="size-full wp-image-21759" srcset="/wp-content/uploads/2016/12/IMG_2371.jpg 640w, /wp-content/uploads/2016/12/IMG_2371-300x225.jpg 300w, /wp-content/uploads/2016/12/IMG_2371-207x155.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /><p class="wp-caption-text">Angular2サイド。左がlaco、右が83</p></div>

<h4>モデレーター</h4>

<ul>
<li><b>shumpei</b> (<a href="http://twitter.com/Shumpei" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">白石 俊平</a>) (HTML5 Experts.jp編集長)</li>
</ul>

<p>また今回、フレームワークを比較するための項目を以下のように洗い出してみました。基本的にこの流れに沿って進めたいと思いますが、脱線は大歓迎ですので、皆さんご自由にご発言いただいて構いません。（編集部注: 前半は「テンプレート」まで）</p>

<ul>
<li>開発⾔語</li>
<li>アーキテクチャ</li>
<li>ビルドツール</li>
<li>ルーティング</li>
<li>テンプレート</li>
<li>スタイリング</li>
<li>コンポーネント以外の処理</li>
<li>ツールサポート</li>
<li>テスト</li>
<li>パフォーマンス</li>
<li>サーバサイドレンダリング</li>
</ul>

<p>では早速始めましょう！</p>

<h2>開発言語</h2>

<p><b class="speaker shumpei">shumpei</b> まずは開発言語について語っていただければと思います。Reactから聞いてみたいと思いますが、Reactを使った開発は基本的にどんな言語を使うのでしょうか？</p>

<p><b class="speaker koba04">koba04</b> 基本的にはBabelを使って、ES6以降のコードをES5に変換しつつ開発しますね。でも、TypeScriptを使う人もいます。<strong>Babelの作者はFacebookにいたりする</strong>ので、基本的にはBabelだと楽ですね。</p>

<p><b class="speaker shumpei">shumpei</b> なるほど。Angular 2のほうはいかがですか？</p>

<p><b class="speaker laco">laco</b> 基本的には開発言語はJS, TypeScript, あとDartがあります。</p>

<p><b class="audience">会場</b> (笑)</p>

<p><b class="speaker laco">laco</b> いや、Dartは笑いどころじゃないでしょう(笑)。
公式に推奨されているのはTypeScriptです。ES6書いてBabelでもいいし、ES5でも書けることは書けますが、結構キツイんで、基本的にはTypeScriptで書くのがデファクトになってます。</p>

<p><b class="speaker 83">83</b> ちょっと待って下さい。結局なんの言語で書きますか、というのが重要で。Reactだったらどの言語、Angularだったらどの言語、っていう <strong>質問がおかしい</strong> 。</p>

<p><b class="speaker shumpei">shumpei</b> そうですか…すいません。</p>

<p><b class="speaker 83">83</b> 大きいものだったらTypeScriptのほうがいいし、小さいものだったらAngular 2でもES6とBabelのほうがサクサク作れます。Angular 2はTypeScript専用だよね、ということはよく言われますがそれは違うと思います。</p>

<p><b class="speaker shumpei">shumpei</b> ちなみに、BabelでAngular 2を書くというのは全然ありなんでしょうか？</p>

<p><b class="speaker laco">laco</b> 全然ありですよ。そのためのプラグインも、 <a href="https://github.com/shuhei/babel-angular2-app" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Shuhei Kagawaさんという方が作ってます</a> 。Flowの記法とか使って、型があるように書けます。</p>

<p>あ、一つReactサイドに聞きたかったんですが、JSXってみんながみんな使うもんなんでしょうか？</p>

<p><b class="speaker yosuke_furukawa">yosuke_furukawa</b> そうだと思います。ぼくもJSXなしでやってみようと思ったこともあるんですけど… <strong>結論としては、(JSXが) ないとダメだなと (笑)。</strong> 結局HTMLっぽく書きたくなるんですよ。</p>

<p>ちなみにさっきの言語の話を少し深掘りしたいんですけど、言語は規模で決まるというのは確かにそのとおりだと思うんですが、一方でエコシステムとかを見ると、BabelをES6じゃない言語で書いてエクスポートしてる例ってあんまりないんですよね。</p>

<p>例えばTypeScriptでライブラリ書いてエクスポートしてるなんてあんまりない。なので、エコシステム全体としては、どっちの言語がより慣れているかという度合いはあるのかなと。そういう意味では、ReactはBabelでAngular 2はTypeScript、というのはあるんじゃないかと思います。</p>

<p><b class="speaker 83">83</b> そうですね、そういう意味で言うと、(Angular 2も)公式サイトのチュートリアルとかも全部TypeScriptで書かれていたりするので、そういう住み分けとかは色がはっきりしているかなと思います。
ちなみにReact陣営に聞きたいんですけど、TypeScriptは「GoogleがMicrosoftと手を組んだ」なんてよく言われてますが、(React開発元のFacebookが開発している) Flowってどうなんですか？</p>

<p><b class="speaker yosuke_furukawa">yosuke_furukawa</b> 実際、React自身はあんまりFlowでっていう話はないです。(Reactコンポーネントの) propTypesを、Flowで書けるようにしよう、って話は進んでるみたいですが。</p>

<p>「propTypesで型チェックをしていく」というのがあんまり綺麗じゃないというか、書き方として洗練されている気がしない。なのであれをFlow側に寄せていこうという活動はあるみたいです。</p>

<p><b class="speaker koba04">koba04</b> FacebookがFlowを強制してくるってことは全然ないですね。propTypeを置き換えるときも、FlowかTypeScriptか、好きなのを使えばいいという感じです。
そこは、フレームワークが特定の型システムに依存する必要はないので、好きに使っていけばという感じです。</p>

<p><b class="speaker shumpei">shumpei</b> ちなみに、ご存じない方もいらっしゃるかもしれないので、<strong>Flowってなんでしょうか？</strong></p>

<p><b class="speaker koba04">koba04</b> Flowは、静的な型チェックをするためのライブラリです。まあ、思想としてはもっと踏み込んでいて、JavaScriptでハマりがちなコードとかを静的解析して、静的な型付け以外のチェックをやっていこうと。</p>

<p>そういう意味では、ESLintとかもカブる部分がありますね。例えばnullチェックをしているかどうかとかも確認できたりとか。静的型付け以上に、JavaScriptでハマりがちなエラーをチェックするためのツールという面が大きいかなと思います。</p>

<p><b class="speaker shumpei">shumpei</b> コードそのものは、JavaScriptで書くということですね。</p>

<h2>アーキテクチャ</h2>

<p><b class="speaker shumpei">shumpei</b> 次の話題はアーキテクチャについてですが、アーキテクチャというとぼんやりしてますね…。これぼくなんでこのお題を出したんだっけな。えーと…、あ、思い出した。Fluxとかの話をしようと思ったんだった。FluxやReduxなど、アーキテクチャに関してちょっとご説明をお願いしてもいいですか？</p>

<p><b class="speaker yosuke_furukawa">yosuke_furukawa</b> 基本的にReactだけだと、イベントや状態を管理する仕組みがないんです。ReactってViewのライブラリなので。Webアプリって、APIサーバを叩いてデータをもらってきてそれをレンダリングするとか、そういうのが普通ですよね。そういうことをしようと思ったら、Reactだけじゃ厳しいんです。そういう時に、イベントを管理する仕組み、あと状態を管理する仕組みっていうのが必要になってくる。そういう時に必要になってくるのがFluxであったり、Reduxであったりというライブラリです。</p>

<p>Fluxはライブラリというよりは「思想」というか、デザインパターンに近いですね。イベントを管理するための、Observerパターンを言い換えたというか。あれねえ、何がすごいかって、名前を付けたのがすごいですよね。カッコいいですよね。<strong>名前の勝利</strong>です(笑)</p>

<p>そういう (Fluxという) 考え方が浸透してきたところにReduxっていうのが出てきて、今一番流行っているライブラリです。</p>

<p>ただひとつ間違えちゃいけないのは、ReactとFlux、ReactとReduxを組み合わせたからといって、Angularほどの「フレームワーク」といえるかというとそこまでいってない。
ただライブラリを組み合わせただけのものでしかなくて。<strong>さらに、その上で自分のレールを作っていく必要があるんじゃないかなとは思います。</strong></p>

<p><b class="speaker shumpei">shumpei</b> なるほど、ReactはReactだけで完結しないと。一方Angular 2のほうは「One Framework」だそうですね。</p>

<p><b class="speaker 83">83</b> Angular 2の話をする前に、AngularJS(AngularJS 1)のほうに一旦戻ろうかなと思うんですが。そもそも1のころは、エコシステムが「Angular World」だったと。</p>

<p>まだ今あるようなES6のモジュールとかがなかった時に、それでもモジュールの仕組みが欲しいとか、そういう要望があったと。なので、<code>angular.module()</code>の中に書いていくというのがあったんですね。</p>

<p>で、それがあったからAngularはエコシステムに乗っていない、一方でReactは乗っているというような分断が起きはじめました。
それ自体は2年前くらいは正しかったのですが、そのイメージをAngular 2になっても引きずっている方がまだおられるんじゃないかというのが気になっています。</p>

<p><b class="speaker 83">83</b> 私はAngular 2を「フレームワーク」と言われることは好きじゃなくて、<strong>Angular 2は「ライブラリ」だと思っている</strong>んですよね。なんでかっていうと、Angular 2にデータを保存しておくものだったり、データのやり取りをするためのものっていうのが、別にAngular 2にはないんです。</p>

<p>Angular 2の特徴ってテンプレートとDIとかあると思うんですけど、実際にはAngular 2だけで全て事足りるかというとそうでもないし、そこは結構割り切ってAngular 2は好きなフレームワークと組み合わせられるようにもなっている。</p>

<p>その上で、Angular 2をどうやって使うかというと、RxJSがよく出てくると思います。RxJSはストリームやイベントを扱うためのライブラリで、FluxのObservableパターンと同じく、何か変化があるまでは動かない。
何か変化がemitされたときにsubscribeしてる側で値を書き換える。それでテンプレートの描画が変わると。そういう意味では、今時代の変化が、Observableパターンに来てるんじゃないかなと思います。</p>

<p><b class="speaker shumpei">shumpei</b> ちなみにこれ、ご存知だったらでいいんですけど、Angular 2とReduxを組み合わせてみた、みたいな話もあるんですけど、そうしたことをする利点とかってなんなのでしょうか？</p>

<p><b class="speaker 83">83</b> 私は実際それをやってみて、別のイベントで発表したこともあるのですが、ぶっちゃけそのときは相当disりまして(笑)。
Reduxをdisったわけじゃないんです。Angular 2とReduxという組み合わせをdisったんです。Reduxは中立なライブラリとは謳われているのですが、実際にはReactを前提として作られたライブラリなので、まあそうなるわな、という感じでした。</p>

<p><strong>Angular 2とReduxの組み合わせがなぜいけてないかというと、DIとの相性が悪い</strong>んです。
ReactにはDIという考え方が全くないし、ReduxもDIを全く無視している設計になっている。</p>

<p>なので、Angular 2はDIできるのに、Reduxと組み合わせると、ReduxのReducerの中では一切DIできない。
何のためにDIができるAngular 2の中でReduxを使うのか。そこだけ別世界に飛ばされるような感じでした。</p>

<p><b class="speaker laco">laco</b> ざっくり言うとReduxにしてもFluxにしても、シングルトンなステートがあって、ステートの変更を検知してコンポーネントがデータを受け取って、コンポーネントがデータを書き換えて…っていうのをくるくるやるわけじゃないですか。</p>

<p>で、シングルトンってAngular 2だとDIで実現するんですよ。なので、Reduxいらないんですよね。仕組み、レールがすでにあって、あとはステートを持つやつを書くだけで、あとはDIでどうとでもなる。
だから、Angular 2は結局、DIでどうとでもなります。</p>

<p><b class="speaker shumpei">shumpei</b> Reduxと組み合わせたみたいな記事をたまに見かけるんですが、それはAngular 2に足りないものがあって、Reduxがそれを補うのかなとかって勝手に想像していたんですが、別にそんなことないよ、って感じでしょうか。</p>

<p><b class="speaker laco">laco</b> たぶん<strong>バズワード組み合わせただけ</strong>じゃないかな、と(笑)</p>

<p><b class="speaker shumpei">shumpei</b> なるほど(笑)。ちなみに例えば、ReactとRxJSを組み合わせる、みたいなバズワードの組み合わせ方とかはないんでしょうか。</p>

<p><b class="speaker koba04">koba04</b> もちろんそこは自由にできて、ReduxとRxJSを組み合わせるための<a href="https://github.com/redux-observable/redux-observable" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">redux-observable</a>というのをRxJSの作者が作ってたりします。RxJSを使いたい場合はそういう選択肢もある。</p>

<p>ただ、APIからデータ取ってくるだけだったら<code>Observable</code> (RxJS) 使う必要もなくて<code>EventEmitter</code>で事足りるかもしれないし、そこは自由に選んでくださいという感じですね。</p>

<h2>ビルドツール</h2>

<p><b class="speaker shumpei">shumpei</b> 次はビルドツールですね。ここは意見を戦わせるところでもなくて、ただ紹介するだけでいいのかなとも思いますが、暴走や脱線は大歓迎です。
まずReactでは、ビルドツールには主に何を使いますか？</p>

<p><b class="speaker yosuke_furukawa">yosuke_furukawa</b> 主にwebpackやBrowserifyですね。エコシステム全体がBrowserifyやwebpackを前提として作られたりしますので、それを使うのが普通です。コンポーネント志向なんで、コンポーネントを作ってexport/importするのが当たり前の世界になってます。</p>

<p><b class="speaker shumpei">shumpei</b> Angular 2サイドはいかがですか？</p>

<p><b class="speaker laco">laco</b> ここは何も変わらないですね。webpack使えますし、バンドル (編集部注: 複数のJavaScriptモジュールを1ファイルにまとめること) しないとブラウザでは使えないし。
そういえば、最近npmリポジトリから落ちてくる（npm installでインストールされる）のが、ESモジュールになったんですよ。(requireではなく) import / exportがそのまま書かれている。
なので、webpack2やRollupを使うとTree shaking (編集部注: 不要なコードを「振り落とし」、バンドルサイズを小さくすること) できるというのはありますね。</p>

<p><b class="speaker shumpei">shumpei</b> <a href="https://github.com/systemjs/systemjs" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">SystemJS</a>っていうツールの存在も聞きますが。</p>

<p><b class="speaker laco">laco</b> (笑)</p>

<p><b class="speaker shumpei">shumpei</b> 笑っちゃうんですかw</p>

<p><b class="speaker laco">laco</b> ごめんなさい、ちょっと失笑です。あれはまだちょっと人類には早いって思ってます(笑)。</p>

<p><b class="audience">会場</b> (笑)</p>

<p><b class="speaker shumpei">shumpei</b> どこらへんが人類には早いんでしょう？</p>

<p><b class="speaker laco">laco</b> あれは世界がHTTP/2になるのを待って、出直してきてほしいツールです。importごとにリクエスト飛んだら、(HTTP/1だと)遅すぎて話にならないです。残念ながら。</p>

<p><b class="speaker shumpei">shumpei</b> 1ファイルにバンドルする機能とかはないんでしょうか？</p>

<p><b class="speaker laco">laco</b> ありますけど、それならwebpackのほうがエコシステムが育っているので、そちらでいいんじゃないかな。プラグインとか、Loaderとか。</p>

<p><b class="speaker yosuke_furukawa">yosuke_furukawa</b> SystemJS待つくらいなら、ES Loader待ったほうがいい(笑)。</p>

<p><b class="speaker shumpei">shumpei</b> <a href="http://jspm.io/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">JSPM</a>っていうのがあるみたいですが…、JavaScript Package Managerでしたっけ。</p>

<p><b class="speaker laco">laco</b> あー。あれ、いつまで存在してるんですか？</p>

<p><b class="speaker yosuke_furukawa">yosuke_furukawa</b> その質問誰に聞いてるんですか(笑)。</p>

<p><b class="speaker shumpei">shumpei</b> なるほど、その程度の扱いということで(笑)。では、SystemJSは人類には早すぎるということで、Angular 2やってる方もwebpackやBrowserifyがいいんじゃないかなということですね。</p>

<p><b class="speaker laco">laco</b> Plunkerみたいなオンラインエディタ上でやるぶんには、SystemJS割と便利なんですけどね。ブラウザ上ではバンドルできないので。ただ、プロダクションでは使う用途ないですよね。</p>

<h2>ルーティング</h2>

<p><b class="speaker shumpei">shumpei</b> では次は、細かい話が混じって申し訳ないですが、ルーティングとかに関して言いたいことがあればお聞きしたいのですが。</p>

<p><b class="speaker yosuke_furukawa">yosuke_furukawa</b> これは…<strong>Angularサイド圧勝</strong>じゃないですか？</p>

<p><b class="speaker shumpei">shumpei</b> そうなんですか？</p>

<p><b class="speaker yosuke_furukawa">yosuke_furukawa</b> React完敗ですね。</p>

<p><b class="speaker laco">laco</b> ほんとか？？(笑)</p>

<p><b class="speaker yosuke_furukawa">yosuke_furukawa</b> そもそもルーティングって、React本体には機能がないんです。で、デファクトスタンダード的に使われている<a href="https://github.com/ReactTraining/react-router" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">React Router</a>っていうのがあるんですが、これみんなdisってる(笑) 。
とりあえず使ってみて、「これクソ使えねえな」みたいな話になるんですけど(笑)。</p>

<p>何が使えないかって言うと、ルーティングの時に最初にやってほしいことって「アクションを発火してほしい」んです。
APIを呼び出してデータを取ってくる、ということをしたいとみんな思うと思うんですが、そういうことをやってくれるような感じになってなくて、まず最初にコンポーネントをマウントしちゃうんです。コンポーネント指向なんで。</p>

<p>でも普通みんながやりたいのって、アクションだと思うんですが、それを書くための記法は今のところない。
なのでしょうがないから、真っ白なコンポーネント出してそこでイベント発火させて(データを)取りに行く…みたいなことをみんなやってるんじゃないかな。あんまりよくないです。</p>

<p>なので、ぼくの頭のなかではReact Routerは決定版にはなっていない。決定版になってないがゆえに、デファクトスタンダードとはさっき言ったけど、みんな野良ルーターみたいの作っちゃって、結果今あんまりよくない状態になっている。
…というところが「<strong>圧敗</strong>」ですね(笑)。</p>

<p><b class="speaker shumpei">shumpei</b> 圧敗(笑) では、圧勝側のご意見も聞きたいです。Angularサイドはいかがですか？</p>

<p><b class="speaker laco">laco</b> 今の話をすると、Angular 2もパスとコンポーネントを結びつけるものだという考え方は変わらないです。
ただ、コンポーネントがマウントされるときに呼び出されるフックポイントがあって、そこでリクエストを飛ばして、その結果を持ってマウントができるという仕組みがある。
あと、「ルーティングしてもよいかどうか」というcanActivateみたいな仕組みもあって、出ていくときの仕組みもあって。
そうしたイベントが全部RxJSに乗っていて、ルーティングが起きるときにはまずイベントが発火するので、使いやすくはなっています。</p>

<p><b class="speaker yosuke_furukawa">yosuke_furukawa</b> そういう意味でいくと一応onEnterみたいなのはあるんだけど、そこでデータを拾いに行くのは、推奨しないってことになってまして…(笑)。</p>

<p><b class="speaker laco">laco</b> <strong>今のAngular 2のルーターはとてもよくできているので、今のところは言うことない、っていうくらいの完成度になりました</strong>。</p>

<p><b class="speaker koba04">koba04</b> ぼくは個人的にルーティングにこだわりはないんですが、基本的にはここもライブラリに依存しなくてもいいんじゃないかな、とはずっと思っています。汎用的ないいルーターが出てこないのかな、とは思ってるんですが、あんまり出てこないですね。</p>

<p><b class="speaker laco">laco</b> 確かに。イベントだけ発火してくれればそれでいいですからね。</p>

<p><b class="speaker koba04">koba04</b> そう。ライブラリと関連しているところではないので。誰か作るチャンスだと思います。</p>

<p><b class="speaker shumpei">shumpei</b> ReactやAngularに関係ないルーティングのライブラリがあればいいのに、ということですね。</p>

<h2>テンプレート</h2>

<p><b class="speaker shumpei">shumpei</b> 前半最後のトピックになりそうですが、次は「テンプレート」です。これ盛り上がるのかな…お互いの記法がキモい、とかってdisりあっていただいてもかまわないんです(笑)。</p>

<p><b class="speaker 83">83</b> <strong>JSXもキモい、Angular 2テンプレートもキモい、気に入ったキモいほう使え</strong>、って感じですね(笑)。</p>

<p><b class="speaker laco">laco</b> でもまあ、Angular 2のテンプレートはギリギリHTMLなので、既存のHTMLツールチェインには乗れるわけです。ちなみにJSXってファイル分けられるんですか？「.jsx」みたいなファイルあるんですか？</p>

<p><b class="speaker yosuke_furukawa">yosuke_furukawa</b> 一応あります。Angular 2は分けられるんですか？</p>

<p><b class="speaker 83">83</b> テンプレートの文字列を直接ソースコード中に書くのも、URLで外部ファイルを指定するのも、どちらも可能です。URLを指定した場合はAjaxで取ってきます。</p>

<p><b class="speaker yosuke_furukawa">yosuke_furukawa</b> そこの通信（コスト）はいいんだ？</p>

<p><b class="speaker laco">laco</b> それはwebpackのプラグインで、URLをrequire()に変換してくれるやつがある（<a href="https://github.com/TheLarkInn/angular2-template-loader" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">angular2-template-loader</a>）ので、ありがたく使わせてもらってます。
あとひとつ気になるのは、<strong>JSXってXSSのサニタイズとかやってくれるんですか？</strong></p>

<p><b class="speaker yosuke_furukawa">yosuke_furukawa</b> …えっとですね。…<strong>Angularの圧勝です。</strong></p>

<p><b class="audience">会場</b> (笑)</p>

<p><b class="speaker yosuke_furukawa">yosuke_furukawa</b> 普通にpタグやdivタグの中に入れる文字列はサニタイズしてくれるんだけど、例えばaタグのhref属性とかに対しては、別に何もしてくれません。なので、(属性値に)<code>javascript:〜</code>とかやろうと思えばできちゃう。</p>

<p><b class="speaker laco">laco</b> <code>innerHTML</code>ぶち込みとかも？</p>

<p><b class="speaker yosuke_furukawa">yosuke_furukawa</b> そうです。だから、<code>innerHTML</code>使うときとか、URLをセットする場合とかは、注意しなくちゃいけない。 (URLから)<code>javascript:</code>を省いてやる必要とか、XSS対策についてはケアが必要です。</p>

<p><b class="speaker shumpei">shumpei</b> React本体でそこら辺を対応しようという動きはないんですか？</p>

<p><b class="speaker koba04">koba04</b> JSXって結局ただのオブジェクトに展開されるんですけど、<code>Symbol</code>とかを使って、外から知らないタグを差し込まれたりはしないようになってます。なので、渡された文字列をそのままReact Elementsとして展開するということは出来ないようになっていますけどね。</p>

<p><b class="speaker laco">laco</b> あ、あともう一つ。Web Components対応ってどうなってるんですか？</p>

<p><b class="speaker koba04">koba04</b> 一応Custom Elementは書けるようになっています。あとは、DOMComponentに不正な属性を渡すと警告が出るようになっていて、それはCustom Elementをサポートするための布石です。なので、この後何らかの対応が入ってくるとは思います。</p>

<p><b class="speaker shumpei">shumpei</b> そろそろお時間ですので、これで前半を終わりにしたいと思います。後半も、引き続きよろしくお願いします。</p>

<p><strong><a href="https://html5experts.jp/shumpei-shiraishi/21754/" data-wpel-link="internal">後編に続きます</a></strong></p>
]]></content:encoded>
			</item>
		<item>
		<title>Reactの最新動向とベストプラクティス ── HTML5 Conference 2016セッションレポート</title>
		<link>/koba04/20839/</link>
		<pubDate>Wed, 19 Oct 2016 00:00:17 +0000</pubDate>
		<dc:creator><![CDATA[小林徹]]></dc:creator>
				<category><![CDATA[最新動向]]></category>
		<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[Facebook]]></category>
		<category><![CDATA[React]]></category>
		<category><![CDATA[Redux]]></category>

		<guid isPermaLink="false">/?p=20839</guid>
		<description><![CDATA[連載： HTML5 Conference 2016 特集 (2)2016年9月3日に東京電機大学で開催された「HTML5 Conference 2016」のセッションを特集する第二弾は筆者である私、小林徹が登壇した「 R...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/html5-conf2016/" class="series-403" title="HTML5 Conference 2016 特集" data-wpel-link="internal">HTML5 Conference 2016 特集</a> (2)</div><p>2016年9月3日に東京電機大学で開催された「HTML5 Conference 2016」のセッションを特集する第二弾は筆者である私、小林徹が登壇した「 <a href="http://events.html5j.org/conference/2016/9/session/#session_id_h1" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Reactの最新動向とベストプラクティス</a>
」の内容を解説します。</p>

<p><img src="/wp-content/uploads/2016/10/DSC06341.jpg" alt="" width="640" height="400" class="alignnone size-full wp-image-21355" srcset="/wp-content/uploads/2016/10/DSC06341.jpg 640w, /wp-content/uploads/2016/10/DSC06341-300x188.jpg 300w, /wp-content/uploads/2016/10/DSC06341-207x129.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<h2>Reactの現状</h2>

<p>Reactは、2013年にFacebookが公開した、Viewを作るためのJavaScriptのライブラリーです。</p>

<ul>
<li><a href="https://facebook.github.io/react/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">https://facebook.github.io/react/</a></li>
</ul>

<p>現在のバージョンは<code>v15.3.2</code>です。
<code>v1.0.0</code>から<code>v14.0.0</code>までのバージョンはありません。
「すでに安定していてプロダクションでも利用できる」ことや「セマンティック・バージョニング（<code>パッチ.マイナー.メジャー</code>）に準拠している」ことを示すために、<code>v0.14.8</code>からのバージョンアップ時に<code>v0.15.0</code>ではなく、マイナーのバージョン番号をメジャーにシフトさせて<code>v15.0.0</code>になりました。</p>

<p>Reactの採用事例を見ていきましょう。</p>

<p>Reactを開発しているFacebookは、ウェブページのコメント欄などで部分的にReactを使用しています。
同じくFacebookが運営しているInstagramでは、ウェブページ全体をReactのComponentで構築しています。</p>

<p>Facebook以外の事例を見てみると、NetflixやTwitter、Airbnb、Uberなど多くの企業でReactが使われています。
日本でも、Abema.tvなど大規模にReactが導入されている事例が増えています。</p>

<p>これらは、ReactのDeveloper Toolsを使用することで確認できます。</p>

<ul>
<li><a href="https://github.com/facebook/react-devtools" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">https://github.com/facebook/react-devtools</a></li>
</ul>

<p><img src="/wp-content/uploads/2016/09/Screen-Shot-2016-09-20-at-22.34.23-640x438.png" alt="screen-shot-2016-09-20-at-22-34-23" width="640" height="438" class="aligncenter size-large wp-image-21095" srcset="/wp-content/uploads/2016/09/Screen-Shot-2016-09-20-at-22.34.23.png 640w, /wp-content/uploads/2016/09/Screen-Shot-2016-09-20-at-22.34.23-300x205.png 300w, /wp-content/uploads/2016/09/Screen-Shot-2016-09-20-at-22.34.23-207x142.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>また、Electron製のターミナルソフトであるHypertermは、ReactとReduxを使って作られています。
機能拡張の仕組みを、Reduxのミドルウェアの仕組みで実現するなど興味深い点も多く、ソースコードはGitHubで公開されています。</p>

<ul>
<li><a href="https://github.com/zeit/hyperterm" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">https://github.com/zeit/hyperterm</a></li>
</ul>

<p>他にもJenkinsが、新しいUI ComponentをReactのComponentとして提供しているなど、Reactはまさに「今使われているライブラリー」であることが言えます。</p>

<h2>特徴</h2>

<p>それではまず最初に、Reactの特徴について見ていきましょう。
Reactのサイトのトップには、「Declarative」、「Component-Based」、「Learn Once, Write Anywhere」の3つのキーワードが紹介されています。</p>

<p><img src="/wp-content/uploads/2016/09/Screen-Shot-2016-09-20-at-21.01.03-640x186.png" alt="Reactの特徴" width="640" height="186" class="aligncenter size-large wp-image-21092" srcset="/wp-content/uploads/2016/09/Screen-Shot-2016-09-20-at-21.01.03.png 640w, /wp-content/uploads/2016/09/Screen-Shot-2016-09-20-at-21.01.03-300x87.png 300w, /wp-content/uploads/2016/09/Screen-Shot-2016-09-20-at-21.01.03-207x60.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>「Learn Once, Write Anywhere（一度学べば、どこでも書ける）」は、ReactにとってDOMは<code>react-dom</code>によるただの1つの環境であることを表しています。
<code>react-native</code>などを使うことで、「同じReactの考え方」でiOSやAndroidのような、DOM以外の環境をターゲットにしたアプリケーションを開発できます。</p>

<p>「Write Once, Run Anywhere（一度書けば、どこでも実行できる）」ではないのは、Viewは各プラットフォームのルールや特徴に応じて構築するべきであり、安易に共通化すべきでないことを意味しています。
しかしながらViewに関連しないロジックの多くは共通化できるとしており、実際にFacebookのAds Managerのアプリは、<code>react-native</code>を使うことでiOSとAndroidで80%以上のコードが共通化できているそうです。</p>

<p>それでは、DeclarativeとComponent-Basedについて見ていきます。</p>

<h3>Declarative</h3>

<p>Reactでは、Declarative（宣言的）にComponentを組み合わせてViewを構築します。
宣言的という言葉の通り、状態に対しての「あるべき姿」を宣言するように定義します。</p>

<p>例えば、イベントに対する処理を命令的に記述すると、下記のようになります。</p>

<p></p><pre class="crayon-plain-tag">// elに対する変化を書いている
button.on(‘click’, () =&gt; el.append(child));</pre><p></p>

<p>これを宣言的に書くと、下記のようになります。</p>

<p></p><pre class="crayon-plain-tag">// render関数は、渡されたstateに対するあるべき表示を定義している
render = state =&gt; {
  el.innerHTML = state.map(child =&gt; `&lt;div&gt;${child}&lt;/div&gt;`).join(‘’);
};

// 状態を更新して、render関数に渡す
button.on(‘click’, () =&gt; {
  state.push(child);
  render(state);
};</pre><p></p>

<p>上記の場合、render関数は受け取った<code>state</code>をもとにViewを構築するだけです。
これは、初期表示の場合もイベントによる更新時も常に同じです。</p>

<p>この結果、render関数は<code>state</code>のみに依存し、同じ<code>state</code>からは常に同じViewを構築します。
これは、テストやデバッグを容易にします。</p>

<p>ReactはComponentを使い、宣言的にViewを構築します。</p>

<p></p><pre class="crayon-plain-tag">const View = props =&gt; (
    &lt;div&gt;{props.items.map(item =&gt; &lt;div&gt;{item}&lt;/div&gt;)}&lt;/div&gt;
);</pre><p></p>

<h3>Component-Based</h3>

<p>Reactでは、Componentを作り、組み合わせることでViewを構築します。
Componentは、Appのようなアプリケーションを全体を表すものから、TextBoxのような既存の要素を少し拡張するようなものまで規模は様々です。</p>

<p></p><pre class="crayon-plain-tag">class App extends React.Component {
  constructor(...args) {
    super(...args);
    this.state = {
      text: '',
    };
  }
  render() {
    return (
      &lt;TextBox
        text={this.state.text}
        onChange={text =&gt; this.setState({text})}
      /&gt;
    );
  }
}
const TextBox = (text, onChange) =&gt; (
  &lt;div&gt;
    &lt;input type="text" onChange={e =&gt; onChange(e.target.value} /&gt;
    &lt;p&gt;{text}&lt;/p&gt;
  &lt;/div&gt;
);

ReactDOM.render(
  &lt;App /&gt;,
  document.getElementById('app')
);</pre><p></p>

<p>Componentは、<code>View = Component(State)</code>のような、Viewを作る関数として考えることができます。
Componentが返す<code>View</code>は、ReactElementのツリーとなります。
作成したReactElementのツリーは、ReactDOMによってDOMへと反映されます。
更新時は、更新前のReactElementのツリーと比較して、差分だけがDOMに反映されます。
これがVIRTUAL DOMと呼ばれる部分です。</p>

<p>この差分の反映により、Reactは関数のようにViewの構築を宣言的に書いた場合でも、パフォーマンスの劣化を避けることができます。
先ほど紹介したReactを使わない<code>innerHTML</code>による反映では、毎回DOMを再構築するため、規模が大きくなるとパフォーマンス上問題となります。</p>

<p><img src="/wp-content/uploads/2016/09/Screen-Shot-2016-09-20-at-20.16.55-640x476.png" alt="screen-shot-2016-09-20-at-20-16-55" width="640" height="476" class="aligncenter size-large wp-image-21084" srcset="/wp-content/uploads/2016/09/Screen-Shot-2016-09-20-at-20.16.55.png 640w, /wp-content/uploads/2016/09/Screen-Shot-2016-09-20-at-20.16.55-300x223.png 300w, /wp-content/uploads/2016/09/Screen-Shot-2016-09-20-at-20.16.55-207x154.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<h2>Componentの作り方</h2>

<p>React Componentの作成方法には、下記の4種類あります。</p>

<ul>
<li>Stateless Functional Components</li>
<li>React.Component</li>
<li>React.PureComponent</li>
<li>React.createClass</li>
</ul>

<h3>Stateless Functinal Componenens</h3>

<p>関数によるComponentの定義方法です。</p>

<p></p><pre class="crayon-plain-tag">const Item = ({item}) =&gt; (
  &lt;div&gt;
    &lt;div&gt;{item.name}×{item.count}&lt;/div&gt;
  &lt;/div&gt;
);</pre><p></p>

<p>ただの関数であり、インスタンスも持たないのでStateやライフサイクルメソッドが定義できないなどの制限があります。
ですが最もシンプルな定義方法であり、Componentを作成する際は、まず最初にStateless Functional Componentsで定義できないかを考えることをオススメします。</p>

<p>SFCと省略して記述されることもあります。</p>

<h3>React.Component</h3>

<p>ComponentにStateを持たせたい場合や、ライフサイクルメソッドを使いたい場合にはReact.Componentを使った定義方法を使います。</p>

<p></p><pre class="crayon-plain-tag">class App extends React.Component {
  constructor(...args) { 
    super(...args);
    this.state = {
      user: null,
    };
  }
  componentDidMount() {
    fetch('/api/user')
    .then(res =&gt; res.json())
    .then(user =&gt; this.setState({user}))
    ;
  }
  render() {
    if (this.state.user == null) return &lt;Loading /&gt;;
    return (
      &lt;div&gt;
        &lt;User user={this.state.user} /&gt;
      &lt;/div&gt;
    );
  }
}</pre><p></p>

<h3>React.PureComponent</h3>

<p>パフォーマンスが問題となるような場面では、React.Componentの代わりにReact.PureComponentの利用を検討します。
React.PureComponentを使うことで、PropsとStateに対してのshallowEqual(浅い比較)がshouldComponentUpdateに適用されるようになります。</p>

<p>shouldComponentUpdateは、無駄なrenderメソッドの呼び出しを避けるためのライフサイクルメソッドです。</p>

<p></p><pre class="crayon-plain-tag">class Counter extends React.PureComponent {
  constructor(...args) {
    super(...args);
    this.state = {count: 0};
  }
  render() {
    return (
      &lt;div&gt;
        &lt;p&gt;{this.props.label}:{this.state.count}&lt;/p&gt;
        &lt;button
          onClick={() =&gt; this.setState({count: this.state.count + 1})
        /&gt;
     &lt;/div&gt;
    );
  }
}</pre><p></p>

<p>React.PureComponentは、PropsやStateのデータをイミュータブルに扱っている場合に利用できます。
イミュータブルであることが保証出来ない場合は、React.Componentを使い、<code>shouldComponentUpdate</code>を自ら実装する必要があります。</p>

<p>ただし、最適化は<code>react-addons-perf</code>を使い、問題となっている部分を計測して確認してから行うことをオススメします。</p>

<h3>React.creteClass</h3>

<p>React.createClassは、最初から存在するComponentの作成方法です。
ですが、今後は緩やかに非推奨の方向に進んでいます。</p>

<h3>Componentの拡張</h3>

<p>Reactでは、Componentの拡張を継承ではなく、Higher Order Components(HOC)を使ったCompositionで行うパターンが推奨されています。</p>

<p>Higher Order Componentsとは、高階関数（Higher Order Function）のComponent版と考えることができます。
Higher Order Functionは関数を引数や戻り値とする関数です。</p>

<p><a href="https://ja.wikipedia.org/wiki/%E9%AB%98%E9%9A%8E%E9%96%A2%E6%95%B0" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">https://ja.wikipedia.org/wiki/高階関数</a></p>

<ul>
<li>Higher Order Functionの例</li>
</ul>

<p></p><pre class="crayon-plain-tag">// 何かする関数を受け取って、結果をログ出して返す
const logger = operation =&gt; (...args) =&gt; {
    const result = operation(...args);
    console.log(result);
    return result;
};
const add = logger((a, b) =&gt; a + b);
add(10, 20);
// 30</pre><p></p>

<p>Higher Order Componentsでは、Componentを引数として受け取り、それをラップした新しいComponentを返します。</p>

<ul>
<li>Higher Order Componentsの例</li>
</ul>

<p></p><pre class="crayon-plain-tag">// Componentを受け取って、PureComponentでラップして返す
const pure = Component =&gt; (
  class Pure extends React.PureComponent {
    render() {
      return &lt;Component ...{this.props}/&gt;;
    }
  }
);
const Item = ({name}) =&gt; &lt;div&gt;{name}&lt;/div&gt;;
const PureItem = pure(Item);
// &lt;PureItem name=“foo” /&gt;</pre><p></p>

<p>Higher Order Componentsのパターンは、<code>react-router</code>や<code>react-redux</code>などのライブラリーでも使われています。</p>

<p>また、Higher Order Componentsのパターンを集めた<code>recompose</code>というライブラリーもあります。</p>

<ul>
<li><a href="https://github.com/acdlite/recompose" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">https://github.com/acdlite/recompose</a></li>
</ul>

<p></p><pre class="crayon-plain-tag">// isLoadedによってComponentを出し分ける
const enhance = branch(
  props =&gt; props.isLoaded,
  Component =&gt; Component,
  () =&gt; Loading
);
const LoadUser = enhance(User);
// &lt;LoadUser isLoaded={isLoaded} user={user} /&gt;</pre><p></p>

<h2>State管理</h2>

<p>Reactでは、Componentは<code>View = Component(State)</code>であると紹介しました。
したがって、Componentにはなるべく状態を持たせないことが推奨されます。</p>

<p>これにより、親Componentだけに状態管理が集約します。
親Componentは、子Componentに「状態」と「状態を変更するための関数」を渡します。
子以下のComponentは、それらを受け取り利用するだけです。</p>

<p><img src="/wp-content/uploads/2016/09/Screen-Shot-2016-09-20-at-21.40.54-640x462.png" alt="screen-shot-2016-09-20-at-21-40-54" width="640" height="462" class="aligncenter size-large wp-image-21093" srcset="/wp-content/uploads/2016/09/Screen-Shot-2016-09-20-at-21.40.54.png 640w, /wp-content/uploads/2016/09/Screen-Shot-2016-09-20-at-21.40.54-300x217.png 300w, /wp-content/uploads/2016/09/Screen-Shot-2016-09-20-at-21.40.54-207x149.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p><code>ViewTree = ComponentTree(State)</code></p>

<p>親Componentに状態管理が集約されることで、アプリケーションの状態を把握することが容易になります。
それと同時に、子Componentはほとんどロジックを持たず、状態を受け取りViewを構築するStateless Functional Componentsで定義可能なただの関数になります。
これによりテストも容易になります。
加えて、親のComponentは状態管理、子のComponentは見た目に関してと、役割を明確に分けることができます。</p>

<p>しかしながら、このパターンの場合、親Componentに処理が集中するため、規模が大きくなると管理が難しくなります。
その解決方法として、Facebookが発表したFluxというアーキテクチャがあります。</p>

<p><img src="/wp-content/uploads/2016/09/flux-diagram-white-background-640x319.png" alt="flux-diagram-white-background" width="640" height="319" class="aligncenter size-large wp-image-21086" srcset="/wp-content/uploads/2016/09/flux-diagram-white-background.png 640w, /wp-content/uploads/2016/09/flux-diagram-white-background-300x150.png 300w, /wp-content/uploads/2016/09/flux-diagram-white-background-207x103.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>Fluxでは、状態管理の流れを役割ごとに細かく分割し、React Componentから切り離します。</p>

<p>Fluxの影響を受けているライブラリーとして、Reduxがあります。
Reduxは、状態管理のためのライブラリーです。</p>

<ul>
<li><a href="http://redux.js.org/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">http://redux.js.org/</a></li>
</ul>

<p>Reduxでは、アプリケーションの状態をシリアライズ可能な1つのオブジェクトにまとめます。
状態の更新は、Actionを発行して、Reducerと呼ばれるActionを元に新しい状態を作成する関数によって行われます。</p>

<p><img src="/wp-content/uploads/2016/09/Screen-Shot-2016-09-20-at-20.26.20-640x467.png" alt="screen-shot-2016-09-20-at-20-26-20" width="640" height="467" class="aligncenter size-large wp-image-21087" srcset="/wp-content/uploads/2016/09/Screen-Shot-2016-09-20-at-20.26.20.png 640w, /wp-content/uploads/2016/09/Screen-Shot-2016-09-20-at-20.26.20-300x219.png 300w, /wp-content/uploads/2016/09/Screen-Shot-2016-09-20-at-20.26.20-207x151.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>Reduxでは、React ComponentをContainer ComponentとPresentational Componentの2つの役割に分けます。
それぞれの役割は以下の通りです。</p>

<p><img src="/wp-content/uploads/2016/09/Screen-Shot-2016-09-20-at-20.27.15-640x465.png" alt="screen-shot-2016-09-20-at-20-27-15" width="640" height="465" class="aligncenter size-large wp-image-21088" srcset="/wp-content/uploads/2016/09/Screen-Shot-2016-09-20-at-20.27.15.png 640w, /wp-content/uploads/2016/09/Screen-Shot-2016-09-20-at-20.27.15-300x218.png 300w, /wp-content/uploads/2016/09/Screen-Shot-2016-09-20-at-20.27.15-207x150.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>Reduxでは、データはシリアライズ可能なオブジェクトとして単一のStoreに保持されるため、各処理は入力を受け取り入力に応じた結果を出力するただの関数として実装できます。</p>

<ul>
<li>アクションの発行 &#8211; <code>action = ActionCreator([event])</code></li>
<li>状態の更新 &#8211; <code>newState = Reducer(state, action)</code></li>
<li>状態の取得 &#8211; <code>props = Selector(state)</code></li>
</ul>

<p>これにより、各部分もPresentational Componentのように簡単にテストができます。</p>

<p>状態と処理を切り離し、ActionとStateをシリアライズ可能なオブジェクトにすることは、デバッグや状態の再現を容易にします。
それを利用したRedux DevTools Extensionでは、Actionを記録して任意のActionの流れを再現するだけでなく、指定したActionの流れをJSONとしてインポート・エクスポートできます。
これにより、処理の流れを複数人で共有したり、エラーがあった場合にサーバーに送信することで、状況の再現が可能になります。</p>

<p><img src="/wp-content/uploads/2016/09/Screen-Shot-2016-09-21-at-1.26.03-PM-640x480.png" alt="screen-shot-2016-09-21-at-1-26-03-pm" width="640" height="480" class="aligncenter size-large wp-image-21097" srcset="/wp-content/uploads/2016/09/Screen-Shot-2016-09-21-at-1.26.03-PM.png 640w, /wp-content/uploads/2016/09/Screen-Shot-2016-09-21-at-1.26.03-PM-300x225.png 300w, /wp-content/uploads/2016/09/Screen-Shot-2016-09-21-at-1.26.03-PM-207x155.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<ul>
<li><a href="https://github.com/zalmoxisus/redux-devtools-extension" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">https://github.com/zalmoxisus/redux-devtools-extension</a></li>
</ul>

<p>Reduxを使う場合、副作用や非同期処理の扱いを、Middlewareのレイヤーで吸収します。
Middlewareは発行されたActionを改変したり別のActionを発行するなど、アプリケーションの処理に大きく影響を与える部分です。
副作用や非同期処理を扱うためのMiddlewareは、すでにたくさん公開されています。
したがって、アプリケーションの要件に適した、副作用や非同期処理の方法を選択できます。</p>

<p>FluxアーキテクチャやReduxは、必要と感じるまで利用する必要はありません。
ですが、Reduxを使わない場合でも、React ComponentをContainer ComponentとPresentational Componentに分けて考えることは重要です。</p>

<h2>エコシステム</h2>

<p>Reactでは、すでに多くのエコシステムが存在します。
React Componentのテストを簡単に書くための仕組みを提供してくれるEnzymeや、Component単位でデザインを確認しながら開発できるReact StorybookなどOSSからたくさんのライブラリーやツールが公開されています。</p>

<ul>
<li><a href="http://airbnb.io/enzyme/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">http://airbnb.io/enzyme/</a></li>
<li><a href="https://getstorybook.io/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">https://getstorybook.io/</a></li>
</ul>

<p>また、React ComponentやJSXのためのESLintのプラグインも存在します。</p>

<ul>
<li><a href="https://github.com/yannickcr/eslint-plugin-react" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">https://github.com/yannickcr/eslint-plugin-react</a></li>
</ul>

<p>コーディングのスタイルだけでなく、廃止予定のAPIの使用や、ベストプラクティスに沿っているかなど数多くの観点からのチェックが可能です。
ESLintとともに利用をオススメします。</p>

<p><img src="/wp-content/uploads/2016/09/Screen-Shot-2016-09-20-at-20.29.16-640x455.png" alt="screen-shot-2016-09-20-at-20-29-16" width="640" height="455" class="aligncenter size-large wp-image-21089" srcset="/wp-content/uploads/2016/09/Screen-Shot-2016-09-20-at-20.29.16.png 640w, /wp-content/uploads/2016/09/Screen-Shot-2016-09-20-at-20.29.16-300x213.png 300w, /wp-content/uploads/2016/09/Screen-Shot-2016-09-20-at-20.29.16-207x147.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>また、a11yに対するチェックを行う<code>eslint-plugin-jsx-a11y</code>というプラグインもあります。</p>

<ul>
<li><a href="https://github.com/evcohen/eslint-plugin-jsx-a11y" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">https://github.com/evcohen/eslint-plugin-jsx-a11y</a></li>
</ul>

<h2>将来</h2>

<p>Reactは、Facebookが開発しているライブラリーです。
Facebookの内部ではすでに25,000以上のReact Componentがあるそうで、ReactはFacebookの中でも重要な位置付けのライブラリーとなっています。
そのためFacebookが必要としている機能に対する優先度は当然高くなりますが、今後も継続してメンテナンスされることが期待できます。</p>

<p>加えて、OSSとしての役割も重要視されています。
例えば、SVGやcustom elementsの対応のようなFacebookでは必要とされていない機能も必要であればReact本体でサポートされます。
また、ReactのコアチームのミーティングノートをGitHubで公開したり、コマンド1つでReactを使ったアプリケーションの雛型を作成する<code>create-react-app</code>もその1つです。</p>

<ul>
<li><a href="https://github.com/reactjs/core-notes" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">https://github.com/reactjs/core-notes</a></li>
<li><a href="https://github.com/facebookincubator/create-react-app" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">https://github.com/facebookincubator/create-react-app</a></li>
</ul>

<p>前述した通り、Facebookだけでなく多くの企業がReactをプロダクションで使用しています。
そのため、Reactは非互換な変更に対してはとても慎重です。</p>

<p>何かAPIを廃止する場合は、「次のメジャーバージョンで警告の出力と移行プランの提供」、「その次のメジャーバージョンで廃止」という流れになります。
したがって、メジャーバージョンアップで突然動作しなくなることがないように配慮されています。</p>

<p>現在進行中の大きな開発として、「ReactFiber」があります。
ReactFiberは、ComponentとRendererがやりとりする、Reactのコアとなるアルゴリズムを全面的に書き直すものです。</p>

<p>現在は、更新処理からReactElementの差分計算・DOMへの反映までが同期的に行われています。
これは、規模の大きなComponentツリーや60FPSが求められるような場面で問題となることがあります。</p>

<p>ReactFiberでは、更新処理をFiberというタスクの単位で非同期に処理できるようになります。
例えば、アニメーションの更新処理など遅延が許されないものは、<code>requestAnimationFrame</code>を使い可能な限りすぐに反映し、APIのレスポンスや画面に表示されてない部分は、<code>requestIdleCallback</code>を使い多少の遅延を許容するといった具合です。</p>

<p><img src="/wp-content/uploads/2016/09/Screen-Shot-2016-09-20-at-20.30.29-640x468.png" alt="screen-shot-2016-09-20-at-20-30-29" width="640" height="468" class="aligncenter size-large wp-image-21090" srcset="/wp-content/uploads/2016/09/Screen-Shot-2016-09-20-at-20.30.29.png 640w, /wp-content/uploads/2016/09/Screen-Shot-2016-09-20-at-20.30.29-300x219.png 300w, /wp-content/uploads/2016/09/Screen-Shot-2016-09-20-at-20.30.29-207x151.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>ReactFiberは、現在ベースとなる部分が実装中であり、すぐに現在のアルゴリズムと置き換えられるものではありません。
しかしながら、今後注目すべき動向の1つです。</p>

<h2>まとめ</h2>

<p>ReactはComponentを使いViewを構築するためのライブラリーです。
そのためReactが担う範囲は広くありません。しかし、Reactを使うことでクライアントでの状態管理の難しさを排除し、シンプルに考えることができます。</p>

<p>また、Facebookのサイト自体もそうであるように、ReactはSingle Page Applicationではないアプリケーションに対しても、部分的に導入していくことが可能です。
その際に必要となる、設計としては綺麗とは言えないようなAPIも提供しています。</p>

<p>Reactを取り巻くエコシステムは大きくなっており、それらの組み合わせを紹介する記事も多く存在します。</p>

<p>しかしながら、Reactをこれから初めてみようと思っている場合は、最低限の構成で小さく始めることをオススメします。その後、必要だと思った段階で、エコシステムが提供するライブラリーの導入を順番に検討してください。</p>

<p>そうすることで、各ライブラリーが、「何を」問題と考えて「どのように」解決しようとしているのかを理解できるようになります。その結果、多くの情報やライブラリーに振り回されることなく、エコシステムと付き合っていけるようになると考えています。</p>

<h3>上記の基調講演は動画でも公開中です</h3>

<p>当日の資料と動画は下記で公開されていますので、こちらも参照してください。</p>


<!-- iframe plugin v.4.3 wordpress.org/plugins/iframe/ -->
<iframe class="embedly-embed" src="//cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fspeakerdeck.com%2Fplayer%2F9919e9af69054589a3b1ad370a77a634&amp;url=https%3A%2F%2Fspeakerdeck.com%2Fkoba04%2Freactfalsezui-xin-dong-xiang-tobesutopurakuteisu&amp;image=https%3A%2F%2Fspeakerd.s3.amazonaws.com%2Fpresentations%2F9919e9af69054589a3b1ad370a77a634%2Fslide_0.jpg&amp;key=internal&amp;type=text%2Fhtml&amp;schema=speakerdeck" scrolling="no" frameborder="0" 0="allowfullscreen" width="100%" height="500"></iframe>



<!-- iframe plugin v.4.3 wordpress.org/plugins/iframe/ -->
<iframe src="https://www.youtube.com/embed/sNjCELYzEkU" frameborder="0" 0="allowfullscreen" width="100%" height="500" scrolling="yes" class="iframe-class"></iframe>

]]></content:encoded>
		
		<series:name><![CDATA[HTML5 Conference 2016 特集]]></series:name>
	</item>
		<item>
		<title>モバイルUIフレームワークのド本命、Onsen UI 2正式リリース！──React, Angular 2両対応！</title>
		<link>/n_matagawa/20766/</link>
		<pubDate>Wed, 05 Oct 2016 00:19:13 +0000</pubDate>
		<dc:creator><![CDATA[又川 尚樹]]></dc:creator>
				<category><![CDATA[最新動向]]></category>
		<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[システム開発]]></category>
		<category><![CDATA[Angular2]]></category>
		<category><![CDATA[Onsen UI 2]]></category>
		<category><![CDATA[React]]></category>

		<guid isPermaLink="false">/?p=20766</guid>
		<description><![CDATA[連載： React/Angular2時代のWeb開発 (1)先日、本サイトにて公開された React/Angular2時代のUIフレームワーク考──Ionic2、Onsen UI2を語る という記事を受けて、本記事ではO...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/webdev-2016/" class="series-400" title="React/Angular2時代のWeb開発" data-wpel-link="internal">React/Angular2時代のWeb開発</a> (1)</div><p>先日、本サイトにて公開された <a href="https://html5experts.jp/shumpei-shiraishi/20411/" data-wpel-link="internal">React/Angular2時代のUIフレームワーク考──Ionic2、Onsen UI2を語る</a> という記事を受けて、本記事ではOnsen UI 2の具体的な使い方をご紹介していきたいと思います。</p>

<h2>Onsen UI 2 の概要</h2>

<p><img src="/wp-content/uploads/2016/09/blog_onsen_2.png" alt="blog_onsen_2"></p>

<p><a href="https://onsen.io/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Onsen UI</a>はアシアル株式会社が2013年から公開している<a href="https://github.com/OnsenUI/OnsenUI" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">オープンソース</a>のHTML5 UIライブラリです。
HTML5モバイルアプリでの利用に特化した高速な動作性が特徴です。</p>

<p>2016/09/15（日本時間）に次期バージョン「<strong>Onsen UI 2</strong>」の正式版をリリースしました。
AngularJSのロードが必要だったOnsen UI 1と異なり、Onsen UI 2は<strong>単体で動作</strong> します（Web 標準の Custom Elements を利用しています）。</p>

<p>また、Android向けの画面とiOS向けの画面をワンソースで構築できる<strong>Automatic Styling</strong>などの新機能を備えています。</p>

<p><img src="/wp-content/uploads/2016/09/onsen-ui2-automatic-styling.png" alt="onsen-ui2-automatic-styling"></p>

<h2>Hello, World</h2>

<p>空ディレクトリを作成し、以下のコマンドで<code>onsenui</code>パッケージをインストールします。</p>

<p></p><pre class="crayon-plain-tag">npm init --yes
npm install onsenui@2.0.0 --save</pre><p></p>

<p>次に、<code>index.html</code>を以下の内容で作成します。</p>

<p></p><pre class="crayon-plain-tag">&lt;!DOCTYPE html&gt;
&lt;html lang="ja"&gt;
&lt;head&gt;
    &lt;meta charset="UTF-8"&gt;
    &lt;meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"&gt;
    &lt;meta http-equiv="Content-Security-Policy" content="default-src * data:; style-src * 'unsafe-inline'; script-src * 'unsafe-inline' 'unsafe-eval'"&gt;
    &lt;link rel="stylesheet" href="node_modules/onsenui/css/onsenui.css"&gt;
    &lt;link rel="stylesheet" href="node_modules/onsenui/css/onsen-css-components.css"&gt;
    &lt;script src="node_modules/onsenui/js/onsenui.min.js"&gt;&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;ons-page&gt;
        &lt;ons-toolbar&gt;
            &lt;div class="center"&gt;Onsen UI&lt;/div&gt;
        &lt;/ons-toolbar&gt;

        &lt;div style="text-align: center;"&gt;
            &lt;p&gt;Hello World!&lt;/p&gt;
            &lt;ons-button onclick="ons.notification.alert('Onsen UI alert');"&gt;Click Me!&lt;/ons-button&gt;
        &lt;/div&gt;
    &lt;/ons-page&gt;
&lt;/body&gt;
&lt;/html&gt;</pre><p></p>

<p><code>head</code>要素内で読み込まれている<code>onsenui.css</code>, <code>onsen-css-components.css</code>, <code>onsenui.min.js</code>がOnsen UI 2の実体です。</p>

<p>上記3つのファイルの読み込みが完了すると、<code>ons-page</code> や <code>ons-toolbar</code>といった要素がブラウザに登録され、<strong>元々ブラウザに組み込まれている<code>input</code>要素などと同じ感覚で使えるようになります</strong>。</p>

<p>最終的なディレクトリ構成は以下のようになります。</p>

<p></p><pre class="crayon-plain-tag">├── index.html
├── node_modules
│   └── onsenui
└── package.json</pre><p></p>

<p>ブラウザで<code>index.html</code>を開くと以下のような画面が表示されているはずです。
ボタンをクリックするとOnsen UI製のダイアログ（<code>ons-alert-dialog</code> 要素）が表示されます。</p>

<p><img src="/wp-content/uploads/2016/09/onsen-ui2-purejs-01-aligned.png" alt="onsen-ui2-purejs-01-aligned">
<img src="/wp-content/uploads/2016/09/onsen-ui2-purejs-02-aligned.png" alt="onsen-ui2-purejs-02-aligned"></p>

<p>このようにOnsen UI 2は、特殊な知識を必要とすることなく、少しの準備ですぐに使い始めることができます。</p>

<p>なお、今回使用した<code>ons-page</code>, <code>ons-toolbar</code>, <code>ons-button</code>, <code>ons-alert-dialog</code>以外にも、Onsen UI 2はモバイルアプリに不可欠なコンポーネントを数多く揃えています（以下はその例です）。</p>

<p><img src="/wp-content/uploads/2016/09/onsen-ui2-components-02.png" alt="onsen-ui2-components-02"></p>

<p>使用可能なコンポーネントの一覧は <a href="https://onsen.io/v2/docs/js.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Onsen UI 2 Docs</a> にあります。Onsen UI 2を使った開発では、使用可能なコンポーネントとその使い方を公式ドキュメントから探しながら画面を実装していくことになります。</p>

<h2>アプリケーションフレームワークと併用する</h2>

<p>発展的な内容として、Onsen UI 2をアプリケーションフレームワークと併用する方法について解説します。</p>

<p>Onsen UI 2の特徴は<strong>任意のアプリケーションフレームワークと併用できる</strong>点です。実際、React, AngularJS, Angular2, Vue.js, Meteorと一緒に動作させても問題なく動作することを確認しています。</p>

<p>しかし Onsen UI 2のコンポーネントは <code>input</code> 要素などと同じく、DOM要素自体にメソッドが紐づけられているため、<strong>Onsen UI 2単体では</strong>コンポーネントを操作する際にDOM要素への直接アクセスが必要になってしまいます。DOM要素への直接アクセスは、ReactやAngular2などといったDOM要素への直接アクセスを忌避するアプリケーションフレームワークにおいて問題となります。</p>

<p>その問題の解決策として、Onsen UI 2は一部のアプリケーションフレームワークに対して<strong>バインディング</strong>を用意しています。</p>

<p>バインディングを利用すると、DOM要素への直接アクセスを回避し、<strong>各アプリケーションフレームワークの流儀に則って</strong> Onsen UI 2のコンポーネントを操作することができます。</p>

<p>2016/09現在、Onsen UI 2は <a href="https://onsen.io/react/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">React</a>, <a href="https://onsen.io/angular2/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">AngularJS</a>, <a href="https://onsen.io/angular2/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Angular 2</a>, <a href="https://onsen.io/vue/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Vue.js</a> の4種類のアプリケーションフレームワークに対してバインディングを提供しています。</p>

<h3>React と併用する</h3>

<p>Onsen UI 2をReactと併用する場合は <code>react-onsenui</code> パッケージ（<strong>React バインディング</strong>）を使用します。</p>

<p>空ディレクトリを作成し、以下のコマンドで必要なパッケージをインストールします。</p>

<p></p><pre class="crayon-plain-tag">npm init --yes

# Onsen UI本体
npm install onsenui@2.0.0 --save

# アプリケーションフレームワーク （React）
npm install react react-dom --save

# Onsen UIのReactバインディング
npm install react-onsenui@1.0.0 --save

# トランスパイラ （Babel）
npm install babel-core@^5 --save</pre><p></p>

<p>次に、<code>index.html</code> を以下の内容で作成します。</p>

<p></p><pre class="crayon-plain-tag">&lt;!DOCTYPE html&gt;
&lt;html lang="ja"&gt;
&lt;head&gt;
    &lt;meta charset="UTF-8"&gt;
    &lt;meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"&gt;
    &lt;meta http-equiv="Content-Security-Policy" content="default-src * data:; style-src * 'unsafe-inline'; script-src * 'unsafe-inline' 'unsafe-eval'"&gt;
    &lt;link rel="stylesheet" href="node_modules/onsenui/css/onsenui.css"&gt;
    &lt;link rel="stylesheet" href="node_modules/onsenui/css/onsen-css-components.css"&gt;
    &lt;script src="node_modules/onsenui/js/onsenui.min.js"&gt;&lt;/script&gt;
    &lt;script src="node_modules/react/dist/react.min.js"&gt;&lt;/script&gt;
    &lt;script src="node_modules/react-dom/dist/react-dom.min.js"&gt;&lt;/script&gt;
    &lt;script src="node_modules/react-onsenui/dist/react-onsenui.js"&gt;&lt;/script&gt;
    &lt;script src="node_modules/babel-core/browser.min.js"&gt;&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;div id="app"&gt;&lt;/div&gt;

    &lt;script type="text/babel"&gt;
        var App = React.createClass({
            alertPopup: function() {
                ons.notification.alert('Onsen UI alert');
            },

            renderToolbar: function() {
                return (
                    &lt;Ons.Toolbar&gt;
                        &lt;div className='center'&gt;Onsen UI&lt;/div&gt;
                    &lt;/Ons.Toolbar&gt;
                );
            },

            render: function() {
                return (
                    &lt;Ons.Page renderToolbar={this.renderToolbar}&gt;
                        &lt;div style={{textAlign: 'center'}}&gt;
                            &lt;p&gt;Hello World!&lt;/p&gt;
                            &lt;Ons.Button onClick={this.alertPopup}&gt;Click Me!&lt;/Ons.Button&gt;
                        &lt;/div&gt;
                    &lt;/Ons.Page&gt;
                );
            },
        });
        
        ReactDOM.render(&lt;App /&gt;, document.getElementById('app'));
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;</pre><p></p>

<p>最終的なディレクトリ構成は以下のようになります。</p>

<p></p><pre class="crayon-plain-tag">├── index.html
├── node_modules
│   ├── babel-core
│   ├── onsenui
│   ├── react
│   ├── react-dom
│   └── react-onsenui
└── package.json</pre><p></p>

<p>ブラウザで <code>index.html</code> を開くと先ほどと同様の画面が表示されているはずです。</p>

<h3>Angular 2と併用する</h3>

<p>Angular 2をReactと併用する場合はangular2-onsenuiパッケージ（<strong>Angular 2 バインディング</strong>）を使用します。</p>

<p>空ディレクトリを作成し、以下のコマンドで必要なパッケージ・型定義ファイルをインストールします。</p>

<p></p><pre class="crayon-plain-tag">npm init --yes

# Onsen UI本体
npm install onsenui@2.0.0 --save

# Angular 2 アプリのビルドに使用するツール
npm install --global typescript
npm install --global typings
npm install --global webpack

# Angular 2の動作に必要なライブラリ （polyfill）
npm install core-js --save
npm install reflect-metadata --save
npm install zone.js --save
npm install rxjs --save

# Angular 2本体
npm install @angular/core@2.0.0 --save
npm install @angular/common@2.0.0 --save
npm install @angular/compiler@2.0.0 --save
npm install @angular/platform-browser@2.0.0 --save
npm install @angular/platform-browser-dynamic@2.0.0 --save

# Onsen UIのAngular 2バインディング
npm install angular2-onsenui@1.0.0-rc.1 --save

# Angular 2アプリのビルドに必要な型定義ファイル
typings install --global dt~core-js#0.0.0+20160725163759</pre><p></p>

<p>次に<code>main.ts</code>を以下の内容で作成します。</p>

<p></p><pre class="crayon-plain-tag">import { NgModule, CUSTOM_ELEMENTS_SCHEMA, Component } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { OnsenModule, onsNotification } from 'angular2-onsenui';

@Component({
    selector: 'app-root',
    template: `
        &lt;ons-page&gt;
            &lt;ons-toolbar&gt;
                &lt;div class="center"&gt;Onsen UI&lt;/div&gt;
            &lt;/ons-toolbar&gt;

            &lt;div style="text-align: center;"&gt;
                &lt;p&gt;Hello World!&lt;/p&gt;
                &lt;ons-button (click)="alertPopup()"&gt;Click Me!&lt;/ons-button&gt;
            &lt;/div&gt;
        &lt;/ons-page&gt;
    `,
})
export class AppComponent {
    alertPopup() {
        onsNotification.alert('Onsen UI alert');
    }
}

@NgModule({
  imports:      [ OnsenModule ],
  declarations: [ AppComponent ],
  bootstrap:    [ AppComponent ],
  schemas:      [ CUSTOM_ELEMENTS_SCHEMA ],
})
export class AppModule {
}

platformBrowserDynamic().bootstrapModule(AppModule);</pre><p></p>

<p>次に以下のコマンドを実行します。</p>

<p></p><pre class="crayon-plain-tag">tsc --init</pre><p></p>

<p>生成された <code>tsconfig.json</code> を以下の内容に書き換えます。</p>

<p></p><pre class="crayon-plain-tag">{
    "compilerOptions": {
        "moduleResolution": "node",
        "module": "commonjs",
        "target": "es5",
        "noImplicitAny": false,
        "sourceMap": false,
        "experimentalDecorators": true,
        "emitDecoratorMetadata": true
    },
    "exclude": [
        "node_modules"
    ]
}</pre><p></p>

<p>次に以下のコマンドで <code>main.bundle.js</code> を生成します。</p>

<p></p><pre class="crayon-plain-tag"># トランスパイル
tsc

# バンドル
webpack main.js main.bundle.js</pre><p></p>

<p>最後に <code>index.html</code> を以下の内容で作成します。</p>

<p></p><pre class="crayon-plain-tag">&lt;!DOCTYPE html&gt;
&lt;html lang="ja"&gt;
&lt;head&gt;
    &lt;meta charset="UTF-8"&gt;
    &lt;meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"&gt;
    &lt;meta http-equiv="Content-Security-Policy" content="default-src * data:; style-src * 'unsafe-inline'; script-src * 'unsafe-inline' 'unsafe-eval'"&gt;
    &lt;link rel="stylesheet" href="node_modules/onsenui/css/onsenui.css"&gt;
    &lt;link rel="stylesheet" href="node_modules/onsenui/css/onsen-css-components.css"&gt;
    &lt;script src="node_modules/onsenui/js/onsenui.min.js"&gt;&lt;/script&gt;
    &lt;script src="node_modules/reflect-metadata/Reflect.js"&gt;&lt;/script&gt;
    &lt;script src="node_modules/zone.js/dist/zone.min.js"&gt;&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;app-root&gt;&lt;/app-root&gt;

    &lt;script src="main.bundle.js"&gt;&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;</pre><p></p>

<p>最終的なディレクトリ構成は以下のようになります。</p>

<p></p><pre class="crayon-plain-tag">├── index.html
├── tsconfig.json
├── main.ts
├── main.js
├── main.bundle.js
├── node_modules
│   ├── @angular
│   │   ├── common
│   │   ├── compiler
│   │   ├── core
│   │   ├── platform-browser
│   │   └── platform-browser-dynamic
│   ├── angular2-onsenui
│   ├── core-js
│   ├── onsenui
│   ├── reflect-metadata
│   ├── rxjs
│   └── zone.js
├── package.json
└── typings
    ├── globals
    │   └── core-js
    └── index.d.ts</pre><p></p>

<p>ブラウザで<code>index.html</code>を開くと先ほどと同様の画面が表示されているはずです。</p>

<h2>まとめ</h2>

<p>本記事ではOnsen UI 2の具体的な使い方を紹介しました。また、発展的な内容として、Onsen UI 2をReact, Angular 2と併用する方法について解説しました。</p>

<p>アプリケーションフレームワークの進化やUIライブラリの充実により、HTML5によるモバイルアプリの実装の敷居は下がり続けています。</p>

<p>ハイブリッドアプリに続いてProgressive Web Appsが話題となる中、そこで必要となるモバイルアプリライクな UI/UX の実装に対する一つの解として、是非Onsen UI 2を活用していただければと思います。</p>

<p>（追伸: 先日Twitterに<a href="https://twitter.com/Onsen_UI_ja" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">@Onsen_UI_ja</a>を開設しました。日本語での技術的な質問はこちらまでどうぞ）</p>
]]></content:encoded>
		
		<series:name><![CDATA[React/Angular2時代のWeb開発]]></series:name>
	</item>
		<item>
		<title>React Native入門 ─ Hello,Worldからネイティブ連携まで</title>
		<link>/shohey1226/20480/</link>
		<pubDate>Tue, 06 Sep 2016 00:16:23 +0000</pubDate>
		<dc:creator><![CDATA[Kameda Shohei]]></dc:creator>
				<category><![CDATA[最新動向]]></category>
		<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[React]]></category>
		<category><![CDATA[React Native]]></category>

		<guid isPermaLink="false">/?p=20480</guid>
		<description><![CDATA[連載： Web技術でアプリ開発2016 (1)モバイルアプリ開発におけるWeb技術の可能性を探る特集・第一弾でご紹介するのはReact Native。その生い立ち、チュートリアルから、コードベースやUIを記述する言語、パ...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/web-based-apps-2016/" class="series-391" title="Web技術でアプリ開発2016" data-wpel-link="internal">Web技術でアプリ開発2016</a> (1)</div><p>モバイルアプリ開発におけるWeb技術の可能性を探る特集・第一弾でご紹介するのはReact Native。その生い立ち、チュートリアルから、コードベースやUIを記述する言語、パフォーマンスまで解説します。</p>

<h2>概要</h2>

<p>React Nativeは2013年にFacebook社内のハッカソンで生まれたプロジェクトです。2014年にiOSアプリのFacebook Ads ManagerをReact Nativeを用いて開発し、2015年3月にオープンソースとして公開されました。そして、半年後の2015年9月にAndroidをサポートし、今年のF8では、MicrosoftがReact Nativeで<a href="https://github.com/ReactWindows/react-native-windows" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Windowsプラットフォーム（PC, Mobile, Xbox）の開発</a>ができます、という発表がありました。また、<a href="https://github.com/ptmt/react-native-macos" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">macOSアプリの開発</a>、<a href="https://github.com/CanonicalLtd/react-native" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Ubuntuアプリの開発</a>など他のプラットフォームの開発もできるようにするプロジェクトも走っているようです。</p>

<p>React Nativeのコンセプトは、&#8221;Write Once, Run Anywhere”(一つのコードでどこでも動く）ではなく、&#8221;Learn Once, Run Anywhere&#8221;(一度学べば、どこでも動かせる）です。一度React Nativeを理解すれば、どのプラットフォーム上でも同様のコーディングを行って、プラットフォームネイティブなアプリケーションを開発することが出来ます。Githubのスター数は35,000を超え、リリースの頻度も多く、グローバルな視点でみると、非常に熱い技術であると言えます。</p>

<p>（編集部注: 「Write Once, Run Anywhere」は、あらゆるプラットフォームで同一のコードが動作するという、Javaが喧伝していたコンセプトです）</p>

<h2>Hello, World</h2>

<p>以下は、macOS上で開発することを前提としたチュートリアルです。</p>

<p>React Native開発に必要なものは、 Node.js, React Nativeのコマンドラインツール、<a href="https://facebook.github.io/watchman/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Watchman</a>（Facebookによって開発されているファイル監視ツール）になります。Homebrewで下記のようにインストールします。</p>

<p><code>
$ brew install node
$ brew install watchman
$ npm install -g react-native-cli
$ npm -v
3.6.0
$ node -v
v5.0.0
</code></p>

<h3>iOS</h3>

<p>iOSの場合はXcodeが必要です。XcodeはMac App Storeからインストールしましょう。　準備が整ったところで、プロジェクトを作って走らせてみます。</p>

<p><code>
$ react-native init AppByWebTech2016
$ cd AppByWebTech2016
$ react-native run-ios
</code></p>

<p><a href="https://html5experts.jp/wp-content/uploads/2016/08/Simulator-Screen-Shot-2016.08.27-9.57.40.png" data-wpel-link="internal"><img src="/wp-content/uploads/2016/08/Simulator-Screen-Shot-2016.08.27-9.57.40-169x300.png" alt="Simulator Screen Shot 2016.08.27 9.57.40" width="169" height="300" class="alignnone size-medium wp-image-20490" srcset="/wp-content/uploads/2016/08/Simulator-Screen-Shot-2016.08.27-9.57.40-169x300.png 169w, /wp-content/uploads/2016/08/Simulator-Screen-Shot-2016.08.27-9.57.40.png 360w, /wp-content/uploads/2016/08/Simulator-Screen-Shot-2016.08.27-9.57.40-116x207.png 116w" sizes="(max-width: 169px) 100vw, 169px" /></a></p>

<h3>Android</h3>

<p>Androidの場合は、Android Studioが必要なのでインストールしておきます。アプリの起動には、実機をUSBで繋げておくか、Emulatorが必要なので適宜用意します。今回は、<a href="https://www.genymotion.com/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Genymotion</a>(個人利用は無料）を起動しておいて, 下記のコマンドを走らせます。</p>

<p><code>
$ react-native run-android
</code></p>

<p><a href="https://html5experts.jp/wp-content/uploads/2016/08/a468941aa8d025ee9409bc979399be8d.png" data-wpel-link="internal"><img src="/wp-content/uploads/2016/08/a468941aa8d025ee9409bc979399be8d-182x300.png" alt="スクリーンショット 2016-08-27 10.32.12" width="182" height="300" class="alignnone size-medium wp-image-20492" srcset="/wp-content/uploads/2016/08/a468941aa8d025ee9409bc979399be8d-182x300.png 182w, /wp-content/uploads/2016/08/a468941aa8d025ee9409bc979399be8d.png 389w, /wp-content/uploads/2016/08/a468941aa8d025ee9409bc979399be8d-126x207.png 126w" sizes="(max-width: 182px) 100vw, 182px" /></a></p>

<h3>NativeBaseを使う</h3>

<p>これだけだと味気ないので、<a href="http://nativebase.io/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">NativeBase</a>を用いてUIを作ってみたいと思います。NativeBaseはWebでいうBootstrapのようなものです。ボタン等のUIを自分でデザインする必要がなく見栄えの良いインターフェイスを簡単に作ることができます。</p>

<p>では、NativeBaseをインストールしてみましょう。(※react-nativeのバージョンは0.32)</p>

<p><code>
$ cd AppByWebTech2016
$ npm install native-base --save
$ react-native link react-native-vector-icons
</code></p>

<p>index.ios.jsを下記のように変更すると、</p>

<p></p><pre class="crayon-plain-tag">import React, { Component } from 'react';
import { Container, Content, Button, Header, Title, List, ListItem, Badge } from 'native-base';
import { Col, Row, Grid } from 'react-native-easy-grid';
import { AppRegistry, Text, View } from 'react-native';

class AppByWebTech2016 extends Component {
  render() {
    return (
      &lt;Container&gt;
        &lt;Header&gt;
          &lt;Title&gt;Hello World&lt;/Title&gt;
        &lt;/Header&gt;
        &lt;Content&gt;
          &lt;List&gt;
            &lt;ListItem &gt;
              &lt;Badge&gt;1&lt;/Badge&gt;
            &lt;/ListItem&gt;
            &lt;ListItem&gt;
              &lt;Badge primary&gt;2&lt;/Badge&gt;
            &lt;/ListItem&gt;
            &lt;ListItem&gt;
              &lt;Text&gt;List 3&lt;/Text&gt;
            &lt;/ListItem&gt;
          &lt;/List&gt;
          &lt;Grid&gt;
            &lt;Row&gt;
              &lt;Col&gt;
                &lt;Button style={{margin:10}}&gt; Click Me! &lt;/Button&gt;
              &lt;/Col&gt;
              &lt;Col style={{backgroundColor: '#204d74'}}&gt;
                &lt;Text style={{fontSize: 20, color: 'white', margin: 10}}&gt;React Native!&lt;/Text&gt;
              &lt;/Col&gt;
            &lt;/Row&gt;
            &lt;Row style={{backgroundColor: '#00c497'}}&gt;
              &lt;Text style={{fontSize: 24, color: '#333', margin: 10}}&gt;Learn once, Write anywhere&lt;/Text&gt;
            &lt;/Row&gt;
          &lt;/Grid&gt;
        &lt;/Content&gt;
      &lt;/Container&gt;
    );
  }
}

AppRegistry.registerComponent('AppByWebTech2016', () =&gt; AppByWebTech2016);</pre><p></p>

<p>スタイルのことを気にせずボタンを作ることができ、グリッドなども簡単に使用できます。プロトタイピングなどにはもってこいのモジュールとなっています。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2016/08/59dd481d8a7df9a47c7015bc6728d49b.png" data-wpel-link="internal"><img src="/wp-content/uploads/2016/08/59dd481d8a7df9a47c7015bc6728d49b-300x279.png" alt="スクリーンショット 2016-08-27 14.09.20" width="300" height="279" class="alignnone size-medium wp-image-20493" srcset="/wp-content/uploads/2016/08/59dd481d8a7df9a47c7015bc6728d49b-300x279.png 300w, /wp-content/uploads/2016/08/59dd481d8a7df9a47c7015bc6728d49b-207x193.png 207w, /wp-content/uploads/2016/08/59dd481d8a7df9a47c7015bc6728d49b.png 373w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>

<h2>プラットフォーム／ライブラリの特徴</h2>

<table>
<thead>
<tr>
  <th align="left">項目</th>
  <th align="right">説明</th>
</tr>
</thead>
<tbody>
<tr>
  <td align="left">対応プラットフォーム</td>
  <td align="right">iOS, Android, Windows(PC, Mobile, Xbox), macOS※, Ubuntu※</td>
</tr>
<tr>
  <td align="left">コードベースは（ほぼ）完全に統一できるか？</td>
  <td align="right">統一できない（実際は7,8割は共有できる）</td>
</tr>
<tr>
  <td align="left">UIを記述する言語</td>
  <td align="right">JavaScript, React, スタイルシート</td>
</tr>
<tr>
  <td align="left">UIはネイティブか、Webか</td>
  <td align="right">WebViewではない。ネイティブもしくはJSとのハイブリットで実現</td>
</tr>
<tr>
  <td align="left">パフォーマンス</td>
  <td align="right">ネイティブ同等</td>
</tr>
<tr>
  <td align="left">ネイティブな機能を呼び出せるか？</td>
  <td align="right">APIを通じて自由に呼び出せる</td>
</tr>
</tbody>
</table>

<p>※コミュニティがサポート</p>

<p>以下に、上の表を補足します。</p>

<h3>対応プラットフォーム</h3>

<p>私が確認したのはiOSとAndroidですが、前述した通り、下記のプラットフォームでReact Nativeの方法でNativeアプリを動かすことができるようです。</p>

<ul>
<li>iOS</li>
<li>Android</li>
<li>Windows(PC, Mobile, Xbox)</li>
<li>MacOS</li>
<li>Ubuntu</li>
<li>Browser※1</li>
</ul>

<p>※１<a href="https://github.com/necolas/react-native-web" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">React Native for Web</a>というChrome, Firefox, Safari &gt;= 7, IE 10, Edge.のBrowser上でReact Nativeコードを動かすというプロジェクトさえ存在します。</p>

<h3>コードベースは（ほぼ）完全に統一できるか？</h3>

<p>残念ながら完全には統一できません。現実には各プラットフォームの作法（例えば、iOSはtabbarは下部、Androidは上部）
が存在し、完全に同じにすべきかというのは別の議論が必要な気がします。ただ<a href="https://www.quora.com/How-much-will-you-be-able-to-share-code-between-Android-and-iOS-with-React-Native" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">85%は同じコードを再利用できた</a>といった話もないわけではありません。ビジネスロジック部分は統一させ、UIは個別のコードで実現するというのが、コードの再利用＋ネイティブの作法の両面を考慮に入れたReact Nativeの流儀だと言ってよいでしょう。</p>

<h3>UIを記述する言語</h3>

<p>コードはJavaScript(ES6), コンポーネントはReact, デザインはスタイルシートを用いて記述していきます。
スタイルシートはCamel記法となるのでCSSのbackground-colorがbackgroundColorという属性になり、非常に馴染みの深いものになります。
React Nativeは、レイアウトを行うためにFlexboxを用います。最近のWebブラウザでは広くサポートされているので、ご存じの方も多いことでしょう。</p>

<p>ES6やReactは確かに学習コストがあります。しかし、Web業界で生きているひとは少なくとも触っておくべき技術でしょう。React Nativeでのアプリ開発の経験が逆にWebに生かすというようなことも起きるかもしれません。</p>

<h3>パフォーマンス</h3>

<p>ネイティブのコンポーネントを利用する限り、ネイティブと同等のパフォーマンスになると言ってよいでしょう。パフォーマンスの最適化を開発者に意識させないようにすることがReact Nativeが実現しようとしていることです。</p>

<p>しかし、<a href="http://facebook.github.io/react-native/releases/0.32/docs/performance.htm" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">公式のドキュメント</a>によると、現実には何点か難しい箇所があると述べられています。</p>

<p>React Nativeは下図のようにスレッドが走っています。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2016/08/8E2942F7-B660-46DC-85BA-58DA362472DB.png" data-wpel-link="internal"><img src="/wp-content/uploads/2016/08/8E2942F7-B660-46DC-85BA-58DA362472DB-300x167.png" alt="8E2942F7-B660-46DC-85BA-58DA362472DB" width="300" height="167" class="alignnone size-medium wp-image-20497" srcset="/wp-content/uploads/2016/08/8E2942F7-B660-46DC-85BA-58DA362472DB-300x167.png 300w, /wp-content/uploads/2016/08/8E2942F7-B660-46DC-85BA-58DA362472DB-207x115.png 207w, /wp-content/uploads/2016/08/8E2942F7-B660-46DC-85BA-58DA362472DB.png 622w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>

<p><a href="https://www.youtube.com/watch?v=0MlT74erp60" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">React.js Conf 2016 &#8211; Tadeu Zagallo &#8211; Optimising React Native: Tools and Tips</a>より転載</p>

<p>端的に言うと、JavaScriptのビジネスロジックが動くJSスレッド上で時間のかかる処理を行うと、UI出力時に遅延が起きてしまうケースがあります。
もしパフォーマンスに影響が出たときは、このJSスレッドを意識してコードを見直してみる必要があります。</p>

<p>今年のReact Confの発表でも言及されていましたが、Facebookは社内にReact Nativeのパフォーマンスチームを作ってパフォーマンスを継続的に改善しています。彼らがリソースを割いて注力している部分でもあるので、これからも改善されていく部分だと思います。</p>

<h3>UIはネイティブか、Webか</h3>

<p>WebViewを使わないという観点でWebではありません。ネイティブのライブラリを呼び出すAPIが多いですが、JSとのコードのハイブリッドといったイメージでしょうか。UIの動作は非常にネイティブライクです。</p>

<h3>ネイティブな機能を呼び出す方法</h3>

<p>React Nativeとネイティブ間を受け渡すようなAPIが用意されています。
これを使うことで容易にネイティブからの値を受け取ったり、受け渡したりすることができます。
この程よい抽象化があることで、現行のiOSアプリにも組み込むことが可能となります。
実際、Facebookのアプリでも一部はReact Nativeで書かれてると言っています。</p>

<p>今回は非常に簡単な例ですが、React Native側で２つの数字を渡しネイティブ側で和を求めて返すメソッドを用いて説明します。(今回はiOS）</p>

<p>まずは、Xcodeで<code>ios/AppByWebTech2016.xcodeproj</code>をOpenし、新規作成からCocoaClassを選び、適当なSubクラスを選びます。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2016/08/ED821C61-EBBF-4046-B1F7-C2C177606302.png" data-wpel-link="internal"><img src="/wp-content/uploads/2016/08/ED821C61-EBBF-4046-B1F7-C2C177606302-300x151.png" alt="ED821C61-EBBF-4046-B1F7-C2C177606302" width="300" height="151" class="alignnone size-medium wp-image-20501" srcset="/wp-content/uploads/2016/08/ED821C61-EBBF-4046-B1F7-C2C177606302-300x151.png 300w, /wp-content/uploads/2016/08/ED821C61-EBBF-4046-B1F7-C2C177606302-207x104.png 207w, /wp-content/uploads/2016/08/ED821C61-EBBF-4046-B1F7-C2C177606302.png 560w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>

<p><a href="https://html5experts.jp/wp-content/uploads/2016/08/EF401AE0-3C72-41CE-BA43-95D68531F7B6.png" data-wpel-link="internal"><img src="/wp-content/uploads/2016/08/EF401AE0-3C72-41CE-BA43-95D68531F7B6-300x210.png" alt="EF401AE0-3C72-41CE-BA43-95D68531F7B6" width="300" height="210" class="alignnone size-medium wp-image-20502" srcset="/wp-content/uploads/2016/08/EF401AE0-3C72-41CE-BA43-95D68531F7B6-300x210.png 300w, /wp-content/uploads/2016/08/EF401AE0-3C72-41CE-BA43-95D68531F7B6.png 640w, /wp-content/uploads/2016/08/EF401AE0-3C72-41CE-BA43-95D68531F7B6-207x145.png 207w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>

<p>すると、AppNativeSum.hとAppNativeSum.mができると思います。
このファイルを下記のように書き換えます。RCT_*(ReaCTの略らしい）の接頭辞がついたAPIをReact Nativeが提供しています。Callbackを用いて返す方法もありますが、今回はPromiseを使います。</p>

<p></p><pre class="crayon-plain-tag">#import "RCTBridgeModule.h"

@interface AppNativeSum : NSObject &amp;lt;RCTBridgeModule

@end</pre><p></p>

<p></p><pre class="crayon-plain-tag">#import "AppNativeSum.h"

@implementation AppNativeSum

RCT_EXPORT_MODULE();

RCT_EXPORT_METHOD(sumNumber:(int)val1 val2:(int)val2 resolver:(RCTPromiseResolveBlock)resolve
                  rejecter:(RCTPromiseRejectBlock)reject)
{
  NSInteger val3 = val1 + val2;
  NSString *val3Str = [NSString stringWithFormat:@"%ld", (long)val3];
  resolve(val3Str);
}

@end</pre><p></p>

<p>このメソッドの戻り値は、JavaScriptのPromiseです。通常のPromiseと同様に、async/awaitを使って非同期処理の結果を処理することも可能です。</p>

<p></p><pre class="crayon-plain-tag">import { NativeModules } from 'react-native';
var AppNativeSum = NativeModules.AppNativeSum;

class AppByWebTech2016 extends Component {

  constructor(props){
    super(props);
    this.state = {
      sum: 0
    }
  }

  async componentDidMount(){
    let sum = await AppNativeSum.sumNumber(1,2);
    this.setState({sum: sum});
  }
...</pre><p></p>

<p>ネイティブコードに精通していれば、公式ドキュメントにあるAPIに渡すだけで容易にReact Nativeとネイティブのやりとりができます。</p>

<h2>まとめ</h2>

<p>マレーシアの友人が、彼の国では企業がReact Nativeエンジニアの採用をしていると言っていました(中国でも似たような状況にあるとか)。
日本でもちらほらReact Nativeを採用する会社がでてきているようです。一年半以上経過し、リリース速度が多少遅くなっているといってもどんどん新しいバージョンが出てきて、かつよりよいUIモジュールもでてきています。今こそ、React Nativeを始めてみてはいかがでしょうか。</p>
]]></content:encoded>
		
		<series:name><![CDATA[Web技術でアプリ開発2016]]></series:name>
	</item>
		<item>
		<title>React/Angular2時代のUIフレームワーク考──Ionic2、Onsen UI2を語る</title>
		<link>/shumpei-shiraishi/20411/</link>
		<pubDate>Fri, 02 Sep 2016 00:00:21 +0000</pubDate>
		<dc:creator><![CDATA[白石 俊平]]></dc:creator>
				<category><![CDATA[最新動向]]></category>
		<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[システム開発]]></category>
		<category><![CDATA[Angular2]]></category>
		<category><![CDATA[Ionic2]]></category>
		<category><![CDATA[Onsen UI2]]></category>
		<category><![CDATA[React]]></category>

		<guid isPermaLink="false">/?p=20411</guid>
		<description><![CDATA[連載： React/Angular2時代のWeb開発 (2)読者の皆様こんにちは、編集長の白石です。 先日ふとしたきっかけで、本サイトの認定エキスパートでありアシアル株式会社の社長でもある田中 正裕さんと、Web技術につ...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/webdev-2016/" class="series-400" title="React/Angular2時代のWeb開発" data-wpel-link="internal">React/Angular2時代のWeb開発</a> (2)</div><p>読者の皆様こんにちは、編集長の白石です。</p>

<p>先日ふとしたきっかけで、本サイトの認定エキスパートでありアシアル株式会社の社長でもある<a href="https://html5experts.jp/masahiro/" data-wpel-link="internal">田中 正裕さん</a>と、Web技術について語り合う機会がありました。</p>

<p>ReactやAngular2といった次世代のアプリケーションフレームワークが存在感を増す中で、UIを構築するためのフレームワークはどう進化するのか？</p>

<p>これらのアプリケーションフレームワークをベースとした<a href="http://ionicframework.com/docs/v2/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Ionic2</a>や<a href="https://onsen.io/v2/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Onsen UI2</a>と言ったUIフレームワークについて、それぞれの立場から語り合ってみました。
（田中さんは<a href="https://onsen.io/v2/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Onsen UI2</a>の開発者、白石は<a href="http://ionicframework.com/docs/v2/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Ionic2</a>をかなりヘビーに使い倒しています）</p>

<p>Progressive Web Apps (PWApps)というキーワードが認知を広げる中で、ハイブリッドアプリやモバイルサイトを構築する手段として、これらのフレームワークは存在感を増しています。PWApps、React、Angular2、Cordovaといったキーワードに関心のある方は必読です！</p>

<p>では、本編をお楽しみください。</p>

<h2>対談参加者のプロフィール</h2>

<p><img src="/wp-content/uploads/2013/07/f9ae33ea6273febd996e092fca378753.jpg" alt="田中 正裕" />
<strong>田中 正裕</strong>(アシアル株式会社 代表取締役社長)</p>

<p>ユーザーインタフェース設計からインフラストラクチャー構築まで、最先端の技術を駆使したシステム構築を手がける。特にPHPをはじめとするOSSや、HTML5やJavaScriptといったオープンなアーキテクチャーを用いたシステムの構築に尽力している。モバイルアプリ開発プラットフォーム「Monaca」のプロダクトマネジャーを兼務。</p>

<p><img src="/wp-content/uploads/2015/01/bf985f8ff1bf6f607fcd1950db7ecac7-66x66.jpg" alt="白石 俊平" />
<strong>白石 俊平</strong>(HTML5 Experts.jp編集長)</p>

<p>株式会社オープンウェブ・テクノロジーCEO。2015年12月、「最先端は、ここにある。」を謳うテクノロジー情報キュレーションサービスTechFeedをリリース。Web技術者向け情報メディア「HTML5 Experts.jp」編集長。日本最大（6,500名超）のHTML5開発者コミュニティ「html5j」ファウンダー。Google社公認Developer Expert (HTML5)、Microsoft社公認Most Valuable Professional (IE) などを歴任。著書に「HTML5&amp;API入門」（2010, 日経BP）、「Google Gearsスタートガイド」（2007, 技術評論社）など。監訳に「実践jQuery Mobile」（2013, オライリー）など。</p>

<h2><a href="http://ionicframework.com/docs/v2/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Ionic2</a>と<a href="https://onsen.io/v2/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Onsen UI2</a></h2>

<p><a href="https://html5experts.jp/wp-content/uploads/2016/08/P7141021.jpg" data-wpel-link="internal"><img src="/wp-content/uploads/2016/08/P7141021-640x480.jpg" alt="P7141021" width="640" height="480" class="aligncenter size-large wp-image-20429" srcset="/wp-content/uploads/2016/08/P7141021.jpg 640w, /wp-content/uploads/2016/08/P7141021-300x225.jpg 300w, /wp-content/uploads/2016/08/P7141021-207x155.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p><b>白石:</b> 本日はよろしくお願いします。今回はReact/Angular2時代のUIフレームワークということで、最先端のUIフレームワークについて語る場にしたいと思っています。</p>

<p><b>田中:</b> はい、よろしくお願いします！</p>

<p><b>白石:</b> まずは、<a href="http://ionicframework.com/docs/v2/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Ionic2</a>や<a href="https://onsen.io/v2/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Onsen UI2</a>について馴染みのない読者も多いと思うので、それぞれのフレームワークとぼくらの関わりについて話しましょうか。まずは、両フレームワークの共通点としては、以下の様な点が挙げられるかと思います。</p>

<ul>
<li>どちらもコンポーネント指向のUIフレームワーク。独自のタグを元に、HTMLっぽいテンプレートを記述することでUIを構築していける。</li>
<li>どちらも最初から数多くのUIコンポーネントを備えており、モバイルネイティブに近い見た目のアプリを作れる。</li>
<li>どちらも、Cordovaをベースとしたモバイルアプリ開発（ハイブリッドアプリ）を前提としている。そのため、以下に示すようなCordovaの特徴を備えることになる。

<ul>
<li>ほぼ完全なクロスプラットフォーム性を備える</li>
<li>プラグインを通じて、ネイティブの機能を呼び出すことができる</li>
<li>WebView上で動作するので、ネイティブアプリに比べて動作が遅い</li>
</ul></li>
</ul>

<p><b>白石:</b> で、こうした認識をベースとして、それぞれのフレームワークの違いなどに踏み込んでいければと思います。
まずは田中さんとOnsen UIの関係ですが、田中さんはOnsen UIのメイン開発者ということでいいんでしょうか？</p>

<p><b>田中:</b> 正確に言うと、開発のリードをしている立場ですね。</p>

<p><b>白石:</b> では、開発の優先順位なども田中さんが決定してらっしゃるということですね。チームは何人くらいいるんですか？</p>

<p><b>田中:</b> 以前弊社に所属していた<a href="https://html5experts.jp/anatoo/" data-wpel-link="internal">久保田 光則さん</a>も含めると、4〜5人くらいがフルコミットしている感じですね。</p>

<p>そもそもOnsen UIとは何かというと、バージョン1の時はAngular1をベースとしたUIフレームワークでした。現在開発を続けている<a href="https://onsen.io/v2/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Onsen UI2</a>の大きな特徴は「<strong>アプリケーションフレームワーク非依存</strong>」ということです。</p>

<p></p><pre class="crayon-plain-tag">&lt;!--
Onsen UI2のコード例。
以下の例はAngular2だが、Angular1やReactと組み合わせることも可能
--&gt;
&lt;ons-page&gt;
  &lt;ons-input (change)="onChange()" type="text"&gt;&lt;/ons-input&gt;
  &lt;ons-button&gt;Click Me!&lt;/ons-button&gt;
&lt;/ons-page&gt;</pre><p></p>

<p><a href="https://onsen.io/v2/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Onsen UI2</a>自体はWeb Componentsに則って作られていて、それをReactやAngular2、Angular1、さらにはjQueryなどと組み合わせて利用できます。最近だとVue.jsとか今はMeteorとかいうバインディングも増えていますね。</p>

<p><b>白石:</b> そこがIonicとの大きな違いですね。</p>

<p>ぼくは、先日リリースした<a href="https://techfeed.io/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">TechFeed</a>というアプリで、<a href="http://ionicframework.com/docs/v2/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Ionic2</a>を全面的に採用しました。TechFeedはエンジニア向けのニュースアプリなのですが、Web/メール/モバイルアプリと、様々なクライアントがあります。そのモバイルアプリを開発するにあたって、プラットフォームごとにコードベースを分けたくなかったので、Cordova上で動作するモバイルアプリ用UIフレームワークを探していたんですね。</p>

<p>その際、まだβ版が出たばかりだったAngular2が割とアーキテクチャ的に美しくまとまっていたのと、<a href="http://ionicframework.com/docs/v2/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Ionic2</a>が既にAngular2に対応していたので、採用することにしました。
なので、<a href="http://ionicframework.com/docs/v2/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Ionic2</a>はAngular2をベースにしたUIフレームワークです。Angular2以外では動きません。</p>

<p></p><pre class="crayon-plain-tag">&lt;!--
  Ionic2のコード例。
  タグの名前などは異なるが、あまり変わらない。
--&gt;
&lt;ion-content&gt;
  &lt;ion-input (change)="onChange()" type="text"&gt;&lt;/ion-input&gt;
  &lt;button&gt;Click Me!&lt;/button&gt;
&lt;/ion-content&gt;</pre><p></p>

<p>この、UIフレームワークとアプリケーションフレームワークが密結合（<a href="http://ionicframework.com/docs/v2/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Ionic2</a>）なのか、それとも疎結合（<a href="https://onsen.io/v2/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Onsen UI2</a>）なのかというところが、今日の対談のポイントになりそうですね。</p>

<p>ただこのまま、UIフレームワークありきの議論に入っていく前に、ぼくは一つ確認したいことがありまして。<strong>そもそもUIフレームワークって必要とされているんでしょうか？</strong></p>

<h2>UIフレームワークは必要か？</h2>

<p><a href="https://html5experts.jp/wp-content/uploads/2016/08/P7141034.jpg" data-wpel-link="internal"><img src="/wp-content/uploads/2016/08/P7141034-640x480.jpg" alt="P7141034" width="640" height="480" class="aligncenter size-large wp-image-20430" srcset="/wp-content/uploads/2016/08/P7141034.jpg 640w, /wp-content/uploads/2016/08/P7141034-300x225.jpg 300w, /wp-content/uploads/2016/08/P7141034-207x155.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p><b>白石:</b> 「いらないだろう」という前提で話すわけではなくて、Webの世界にとってコンポーネント指向のUIフレームワークというのはまだ新しい存在なので、そもそも「なぜ必要なのか？」を確認したいのです。とりあえず、フレームワークが必要か不要かで言うと、Webデザイナーさんの中には、フレームワークを嫌がる方も多い気がするのですが。</p>

<p><b>田中:</b> 確かにそういう方もいらっしゃるとは思います。が、（Bootstrapなどのような）CSSフレームワークと、JavaScriptも含めたUIフレームワークは別に考えるべきじゃないかと思います。</p>

<p><b>白石:</b> 確かにそうですね。CSSフレームワークは、デフォルトでそれなりの見た目になるとか、コーディングスタイルが統一されるなどの利点はあると思いますが、フレームワークのスタイルを変更しようとすると途端に面倒だったりしますしね。フレームワーク独自のルールを覚えなくちゃいけないし、最終的には全部リセットしたくなったり（笑）。</p>

<p><b>田中:</b> その通りです。それに、ことモバイルアプリやサイトをWeb技術で作る場合に大事なのって、単なるCSSのプリセットがあることではありません。実際に操作してみた時のスムーズさだったり、アプリ全体から受ける印象だったりと、振る舞いも含めたもっと包括的なUXです。</p>

<p>そういう面で、アプリ全体のUXを統一して、なおかつプラットフォームに馴染んだものにするためには、やはり一貫した枠組みが必要です。それは実際に私がMonacaを運営する上で、お客様からご要望をいただいてきたところでもありますし、だからこそOnsen UIを作ることにも繋がりました。ということで、私はUIフレームワークは確実に必要だと思いますね。</p>

<p><b>白石:</b> なるほど。ただ、UIフレームワークって、寿命が短くないですか？昔はjQuery MobileやKendo UIなんてのもありましたが、今ではあまり使っているという話を聞きません。</p>

<h3>UIフレームワークとアプリケーションフレームワーク</h3>

<p><a href="https://html5experts.jp/wp-content/uploads/2016/08/P7141008.jpg" data-wpel-link="internal"><img src="/wp-content/uploads/2016/08/P7141008-640x480.jpg" alt="P7141008" width="640" height="480" class="aligncenter size-large wp-image-20431" srcset="/wp-content/uploads/2016/08/P7141008.jpg 640w, /wp-content/uploads/2016/08/P7141008-300x225.jpg 300w, /wp-content/uploads/2016/08/P7141008-207x155.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p><b>田中:</b> それは、それらのフレームワークがUI的に古びてしまったというわけではなく、アーキテクチャ的に古いと見なされたから使われなくなってしまったんだと思うんです。JavaScriptアプリケーションのアーキテクチャは、ここ数年目まぐるしく移り変わってきました。jQueryのあとAngular1、React、Angular2, 他にもRiot.jsとかVue.jsなども出てきている。</p>

<p>ですがそれはアーキテクチャの進化であって、UIが進化したわけではありません。例えばUIの進化って、iOS7からフラットデザインになりましたとか、マテリアルデザインが出てきましたとか、そういうことです。こうした進化がすごく早いかと言われると、正直そうは思いません。UIフレームワークが、アプリケーションアーキテクチャの進化に引きずられちゃってたんじゃないか、というのがぼくの思うところです。</p>

<p><b>白石:</b> なるほど、だから<a href="https://onsen.io/v2/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Onsen UI2</a>はアプリケーション・フレームワークに依存しない形で設計されているわけですね。ぼくはTechFeedを<a href="http://ionicframework.com/docs/v2/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Ionic2</a>で作りましたが、それはAngular2の採用を先に決めていたから、というのもあります。というか、その時はまだ<a href="https://onsen.io/v2/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Onsen UI2</a>が今ほど開発が進んでいなかったので、モバイルアプリを包括的に作れるUIフレームワークと、コンポーネント指向のアプリケーションフレームワークの組み合わせが、<a href="http://ionicframework.com/docs/v2/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Ionic2</a> + Angular2しかなかったんですよね。</p>

<p><b>田中:</b> <a href="http://ionicframework.com/docs/v2/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Ionic2</a>はAngular2に強く依存しているわけですが、<a href="http://ionicframework.com/docs/v2/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Ionic2</a>を学ぶには先にAngular2を学ばなくてはならないわけですよね。私はそこを少しもったいないな、と思います。元々私がUIフレームワークで実現したかったことって、「JavaScriptのフレームワークを学ばなくても簡単に使える」ということだったので。</p>

<p><b>白石:</b> 確かに、Onsen UIはそういうところの配慮が行き届いている気がします。ぼくもOnsen UI1の時に使わせていただいていましたが、Webサイト上のサンプルコードが良くできていて、コピペするだけでUIが作れてしまうのが、とても楽ちんでした。</p>

<h3>それぞれのフレームワークが目指すもの</h3>

<p><a href="https://html5experts.jp/wp-content/uploads/2016/08/P7141052.jpg" data-wpel-link="internal"><img src="/wp-content/uploads/2016/08/P7141052-640x480.jpg" alt="P7141052" width="640" height="480" class="aligncenter size-large wp-image-20432" srcset="/wp-content/uploads/2016/08/P7141052.jpg 640w, /wp-content/uploads/2016/08/P7141052-300x225.jpg 300w, /wp-content/uploads/2016/08/P7141052-207x155.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p><b>田中:</b> あと、<a href="http://ionicframework.com/docs/v2/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Ionic2</a>はどことなくUIフレームワークというよりは「プラットフォーム」を目指している気がします。</p>

<p><b>白石:</b> 確かに。Ionicはモバイルアプリを作る際はCordovaを使用するのですが、CordovaもあくまでIonicが規定するプラットフォームの一部というつもりなのか、<code>cordova</code>コマンドをラップした<code>ionic</code>コマンドを提供していますね。また、CordovaプラグインのAPIをラップした <code>ionic-native</code> というモジュールも提供しています。これは、各種プラグインをTypeScriptから使えるようにしてくれているので、結構ありがたくはあるんですが。</p>

<p><b>田中:</b> UIフレームワークを入り口として、プラットフォームに入ってきてください、というスタンスな気がしますよね。
Onsen UIはあくまでUIフレームワークであり、アプリケーションスタックの一部という位置付けなので、そこは思想の違いが現れている気がします。</p>

<p><b>白石:</b> <a href="http://ionicframework.com/docs/v2/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Ionic2</a>はアプリケーションプラットフォームを限定していて、プラットフォームを志向している。<a href="https://onsen.io/v2/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Onsen UI2</a>はアプリケーションプラットフォーム非依存で、ライブラリを指向している。こういう対比になりますね。こうして並べると、個人的には<a href="https://onsen.io/v2/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Onsen UI2</a>の方が設計面で魅力を感じます。</p>

<p><b>田中:</b> ありがとうございます(笑)。</p>

<p><b>白石:</b> ただ、まだ結論を出すのは早い気もしますね。どちらも正式リリース前ですし(笑)。</p>

<p>TechFeedがAngular2と<a href="http://ionicframework.com/docs/v2/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Ionic2</a>を採用しているからというわけではないですが、アプリケーションプラットフォームを限定しているからこその強みもあるかもしれません。ぼくはまだ<a href="https://onsen.io/v2/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Onsen UI2</a>を実際に触ってみたことがないので比較ができないのですが、<a href="http://ionicframework.com/docs/v2/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Ionic2</a>のほうがAngular2との相性とかはさすがにいいでしょうし。先ほど出てきた<code>ionic-native</code>パッケージとかもなかなか便利です。</p>

<p>またぼくらがIonicを採用した理由の一つには、コミュニティの大きさがIonicのほうが大きそうだった、という理由もあります。GitHubのStarの数が、Ionicは25,000、Onsen UIは3,000という違いがあったので。コミュニティの大きさは、Web上の情報量の差にもなって表れてくるので、困ったときに情報を得やすいと思ったのです。</p>

<p>このようにいろんな観点での比較ができそうなので、一概にどちらが優れているとここでは結論付けられなそうですが、こうした議論が読者の皆さんにとって判断の助けになるといいですね。</p>

<p>（編集部: 参考までに、ここまでに出てきた論点や、Web上で得られる内容を比較した表を掲載しておきます）</p>

<table>
<thead>
<tr>
  <th>項目</th>
  <th><a href="http://ionicframework.com/docs/v2/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Ionic2</a></th>
  <th><a href="https://onsen.io/v2/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Onsen UI2</a></th>
</tr>
</thead>
<tbody>
<tr>
  <td>依存するアプリケーションプラットフォーム</td>
  <td>Angular2</td>
  <td>非依存（現時点ではAngular1/2, Reactなど）</td>
</tr>
<tr>
  <td>フレームワークの実装言語</td>
  <td>TypeScript</td>
  <td>ES2015とTypeScript</td>
</tr>
<tr>
  <td>目指す地点</td>
  <td>プラットフォーム？</td>
  <td>ライブラリ</td>
</tr>
<tr>
  <td>GitHub上でのStar数 (2016/8/25時点)</td>
  <td>25,370</td>
  <td>3,216</td>
</tr>
</tbody>
</table>

<p>（UIコンポーネントは現在のところほぼ同数ですが、どちらかにしか実装されていないコンポーネントもいくつかありますし、今後大きく増えていく部分だと思われるため、表からは除外しています）</p>

<h3>今後のWeb技術の展望を語る</h3>

<p><a href="https://html5experts.jp/wp-content/uploads/2016/08/P7141001.jpg" data-wpel-link="internal"><img src="/wp-content/uploads/2016/08/P7141001-640x480.jpg" alt="P7141001" width="640" height="480" class="aligncenter size-large wp-image-20434" srcset="/wp-content/uploads/2016/08/P7141001.jpg 640w, /wp-content/uploads/2016/08/P7141001-300x225.jpg 300w, /wp-content/uploads/2016/08/P7141001-207x155.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p><b>白石:</b> 最後にお聞きしたいんですが、Onsen UIに限らず、今後のWeb技術って、どういう方向に進んでいくとお考えですか？</p>

<p><b>田中:</b> Web技術って、今どんどん開発のバリエーションが増えている状態だと思っています。それはフラグメンテーションと呼べるかもしれない。例えば、Angular2がTypeScriptを、ReactがJSXを使用しているように、です。これらが収束して一つの太い流れができていくのか、このまま個別の進化を続けていくのかは、まだ何ともいえません。</p>

<p><b>白石:</b> テクノロジーのスタックが積み上がっていくにつれ、それぞれの開発手法の間の差異が広がっているというわけですね。こうした状況は、なぜ起きていると考えられますか？</p>

<p><b>田中:</b> 私はMonacaを通じて「ハイブリッドアプリ」、つまりWeb技術でモバイルアプリを作るというところをずっとやってきました。その経験から言うと、モバイルアプリは大きく2パターンあります。一つは長期間のメンテナンスが必要なアプリ。もう一つはキャンペーンなどのワンタイムなアプリケーションですね。前者には強固な基盤が求められるので、Angular2のようなものが求められます。後者はそうではないですね。逆にさくっと作れるようなものが求められます。</p>

<p>こうしたニーズの二分化も理由の一つじゃないかなあとは思っています。</p>

<p><b>白石:</b> なるほど、ニーズが分かれていると。そういう意味でいうと、静的な文書中心の「Webサイト」と、Single Page Application化が進む「Webアプリ」の違いも、フロントエンド技術のフラグメンテーションに一役買っていそうです。「Webサイト」の制作においては、まだまだjQueryは現役ですし、無理にそこを変える必要もなさそうですし。</p>

<p>あと、Web技術の適用範囲が増えてきているというのもあるかもしれませんね。WebVRとか、JavaScriptで動かせる組み込み基板とか。ウェアラブルやロボティクスという分野にも、Web技術が広まっていくとは思います。実際にそれがどれくらい使われるかは未知数ですけども。</p>

<p><b>田中:</b> とはいえWeb技術って、情報技術全体から見るとエッジの技術ではありませんよね。かなりコモディティ化の進んだ、汎用的でメインストリームな技術。</p>

<p><b>白石:</b> 確かに。これだけ技術が進んでも、結局のところHTML/CSS/JavaScriptという基本的な部分はあまり変わっていません。</p>

<p><b>田中:</b> こうしたWeb技術の適用範囲をいかに広げていくか…というのは、個人的な興味として強くあります。いちエンジニアとして、Webのスキルセットをいろんなプラットフォームで使えるよう後支えしたいというのは、私の目指すところです。</p>

<p><b>白石:</b> それは、HTML5 Experts.jpでもぜひ進めていきたいところです。ではそろそろお時間ですね。本日はお付き合いいただき、どうもありがとうございました！</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2016/08/P7140983.jpg" data-wpel-link="internal"><img src="/wp-content/uploads/2016/08/P7140983-640x480.jpg" alt="P7140983" width="640" height="480" class="aligncenter size-large wp-image-20436" srcset="/wp-content/uploads/2016/08/P7140983.jpg 640w, /wp-content/uploads/2016/08/P7140983-300x225.jpg 300w, /wp-content/uploads/2016/08/P7140983-207x155.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>
]]></content:encoded>
		
		<series:name><![CDATA[React/Angular2時代のWeb開発]]></series:name>
	</item>
		<item>
		<title>ポエム駆動開発がエッジすぎる！白石俊平がピクシブの開発環境について、聞いてみた！</title>
		<link>/miyuki-baba/17613/</link>
		<pubDate>Wed, 02 Dec 2015 00:00:03 +0000</pubDate>
		<dc:creator><![CDATA[馬場 美由紀]]></dc:creator>
				<category><![CDATA[最新動向]]></category>
		<category><![CDATA[Assault]]></category>
		<category><![CDATA[ES6]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[React]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[esa]]></category>
		<category><![CDATA[idobata]]></category>
		<category><![CDATA[ピクシブ]]></category>

		<guid isPermaLink="false">/?p=17613</guid>
		<description><![CDATA[次々と登場する開発ツールや言語のバージョンアップ。開発スピードがどんどん早くなるWeb業界ですが、実際に企業の開発現場ではどのように開発環境やツール・体制などを構築しているのか──。 HTML5 Experts.jp白石...]]></description>
				<content:encoded><![CDATA[<p>次々と登場する開発ツールや言語のバージョンアップ。開発スピードがどんどん早くなるWeb業界ですが、実際に企業の開発現場ではどのように開発環境やツール・体制などを構築しているのか──。</p>

<p>HTML5 Experts.jp白石俊平編集長が、根ほり葉ほり聞いちゃうシリーズ・第一弾は、ピクシブを訪問！HTML5 Experts.jpのエキスパートでもある川田寛<a href="https://twitter.com/_furoshiki" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">@_furoshiki</a>さんと片倉<a href="https://twitter.com/geta6" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">@geta6</a>さんにお話を聞いてきました。</p>

<p><img src="/wp-content/uploads/2015/11/pixiv-1.jpg" alt="" width="640" height="469" class="aligncenter size-full wp-image-17614" srcset="/wp-content/uploads/2015/11/pixiv-1.jpg 640w, /wp-content/uploads/2015/11/pixiv-1-300x220.jpg 300w, /wp-content/uploads/2015/11/pixiv-1-207x152.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<h2>クリエイターがやんちゃして遊べる基地ピクシブ</h2>

<p><strong>白石：</strong>まずはピクシブのサービスや、川田さんが今どんな業務を担当しているのか聞かせてください。</p>

<p><strong>川田：</strong>ピクシブでは「創作活動をもっと楽しくする」という理念を持って、いろんなサービスを提供しています。イラスト・漫画・小説が投稿できる「<a href="http://www.pixiv.net/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">pixiv</a>」以外にも、ネットショップサービス「<a href="https://booth.pm/ja" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">BOOTH</a>」やグッズ制作サービス「<a href="https://factory.pixiv.net/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">pixivFACTORY</a>」といったECサービス、お絵かきアプリ「<a href="https://sketch.pixiv.net/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">pixiv Sketch</a>」とか、いろいろな創作活動向けのサービスを提供しています。</p>

<p><img src="/wp-content/uploads/2015/11/DSC08801.jpg" alt="" width="640" height="441" class="aligncenter size-full wp-image-17638" srcset="/wp-content/uploads/2015/11/DSC08801.jpg 640w, /wp-content/uploads/2015/11/DSC08801-300x207.jpg 300w, /wp-content/uploads/2015/11/DSC08801-207x143.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /><span style="font-size: 80%"><strong>▲ピクシブ株式会社　エンジニア　川田寛さん</strong></span></p>

<p>私がメインとして担当しているのは　CtoCのECサービスです。同人イベントなどであつかわれる創作物の頒布を、どうやったらネットの力で便利に変えられるのかって、いつも考えてますね。主に「BOOTH」と「pixivFACTORY」を担当しています。</p>

<p><strong>白石：</strong>グッズ化したり、販売できたりするサービスですよね。ピクシブならではの強みってあります？</p>

<p><strong>川田：</strong>「創作活動をしている人」にフォーカスしているところでしょうね。そういう人たちに愛されるサービスにできていると思っているし、社内の空気としても、クリエーターに対する尊敬があって、彼らをどう幸せにできるのかを考えていたりして。</p>

<p>たとえばBOOTHだと、普通のECサービスじゃ採算があわないという理由で蔑ろにされてもおかしくないような作品を作っている人も、ちゃんと大切にできる。例えば、マニアックすぎて日の目を見ない人たちも気軽に参加できるし、投資できるような仕組みも作っています。普通なら500円くらいでしか売れない作品でも、その価値を認めた人は1000円とか1万円というように、購入者側の評価価格で購入できるような仕組みを作ったりとか。</p>

<h2>朝思いついたことをすぐコードで書くスピード感</h2>

<p><strong>白石：</strong>川田さんは入社したばかりですけど、前職との違いをどう感じてますか？</p>

<p><strong>川田：</strong>前は100年以上歴史があったりとか、受託をメインとしている企業だったので、ピクシブとは何もかもが真逆ですね。社員の年代も若いし、サービスもまだできて7年くらい。開発言語一つとっても、今まではJavaがメインだったのが、RubyやPHP、Scala、Goなど、前の会社だったら絶対に手を出さなかったような言語もガンガン使っています。</p>

<p>開発するものについても、大規模な受託案件で、1年以上先にリリースされるようなウォーターフォール型が多かったのですが、ピクシブは自社開発で、それこそ朝に思いついた良いアイデアはその日のうちにコードを書いて形にしてリリースしたりすることもあります。ユーザーに価値を提供していく上で、とにかくスピード感が命なので、そのために多くの権限を現場に委ねているというかんじがしています。</p>

<p><strong>白石：</strong>全然違うんですね。コードを書くってことは、川田さんはプログラマ寄りの仕事なんですか？</p>

<p><strong>川田：</strong>UIまわりが多く、フロントエンドエンジニアをやってます。サーバーサイドも書くときは書きます。うちの会社はフロントエンジニアが3人いますが、みんな特にフロントエンドだけをやっているという感じではありませんね。iOSとかAndroidを作るアプリエンジニアもいますが、あまり境目がなくて何でもやっているというかんじがします。前職はお客様対応みたいなのが絡むので、SEという言葉がぴったりハマるような仕事だったのですが、今は完全にエンジニアです。コードを書くことで、ユーザーへの価値を発揮しています。</p>

<p><strong>白石：</strong>そうなると、仕様策定は誰がやるんでしょうか。</p>

<p><strong>川田：</strong>大きな機能追加とかロードマップは、ディレクターがまとめたり経営層を巻き込んだりしていますが、そうでないものは現場で考えてスピーディーにやってしまいます。</p>

<p><img src="/wp-content/uploads/2015/11/DSC08879.jpg" alt="" width="640" height="425" class="aligncenter size-full wp-image-17661" srcset="/wp-content/uploads/2015/11/DSC08879.jpg 640w, /wp-content/uploads/2015/11/DSC08879-300x199.jpg 300w, /wp-content/uploads/2015/11/DSC08879-207x137.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /><span style="font-size: 80%">　▲ピクシブ株式会社のオフィスには、いたるところに絵師さんのイラストが描かれている。</span></p>

<h2>ポエムはesa、意見交換・情報共有はidobataで</h2>

<p><strong>川田：</strong>うちの会社にはポエム駆動開発というのがあるんです。コードがかけるだけじゃなくて、創作をする人に対して想いが強い人が入社してくる。エンジニアにも想いが強い人がいっぱいいるので、ポエムを通じて刺激されて作る。</p>

<p><strong>白石：</strong>へえ。川田さんはどんなポエムを書いたんですか？</p>

<p><strong>川田：</strong>新サービスとかユーザーの声とかいろんな話が絡んでてあまりまだ公表できない話も多いのですが。作品を扱っているサービスとしては、やはり、それを求めているユーザーとうまく繋いであげないことには、出展しているクリエーターやアーティストさんにとっても良くないわけで。そこをどう改善していけばいいのか、というお話をしていました。</p>

<p>社内では<a href="https://esa.io/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">esa</a>というツールを使ってポエムを語るんです。このサービスはこうやったら成功するんじゃないかって書くと、みんなが反応を示していく。そうやってどんどんプロダクトを改善したり、新しく作り出したりしていますね。</p>

<p><img src="/wp-content/uploads/2015/11/DSC08785.jpg" alt="" width="640" height="425" class="aligncenter size-full wp-image-17659" srcset="/wp-content/uploads/2015/11/DSC08785.jpg 640w, /wp-content/uploads/2015/11/DSC08785-300x199.jpg 300w, /wp-content/uploads/2015/11/DSC08785-207x137.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p><strong>白石：</strong>現場から上がってくるボトムアップなかんじがいいですね。</p>

<p><strong>川田：</strong>何を作るのかとか、どう改善するかは現場から上げていけますね。経営層も「お前らでドラスティックに変えていってくれ」って言ってくれて。</p>

<p><strong>白石：</strong>チーム体制は何人くらいでやってるんですか？</p>

<p><strong>川田：</strong>うちのチームだと、BOOTHとpixivFactoryであわせて10名弱くらい。両方ともRailsなど同じ道具を使って作っているので、エンジニアはどちらもみている感じですね。</p>

<p><strong>白石：</strong>アジャイルで開発しているんでしたっけ。</p>

<p><strong>川田：</strong>うちのチームではアジャイルと呼べるほど、そこまできっちりしていません。どちらかといえばDevOpsが自然に機能しているという印象。大きな機能リリースに向けた開発はしているけれど、それだけをメインとしてやってはいられない。いま動いているものに問題があれば、そこで対応もしなくてはいけないので。サポートチームのフィードバックであったり、エゴサーチして問題を探って、<a href="https://idobata.io/ja/home" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">idobata</a>で即座に共有されたり。</p>

<p><strong>白石：</strong>エゴサーチを開発チームがしているのはすごい。社内のコミュニケーションツールは<a href="https://slack.com/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Slack</a>じゃないんですね。idobataって、Slackと比べてどうなんですか？使いやすいとか。</p>

<p><strong>川田：</strong>Slackとidobataを使ってはいますが、うちのチームだとidobataの方がメインになりましたね。自分たちの使っている範囲で、機能面にそこまでの違いは感じてはいません。Slackはチームごとで導入してしまっているからか、会社全体として導入しているidobataのほうがオープンに議論が交わされてて。他のチームのスレをみて気軽に意見を言ったり、挙句にプルリクを作って後方支援することもあったり。プロダクトやチームを超えて議論がされていますね。</p>

<h2>タスク管理はカンバン。具体的なタスクはGitHub</h2>

<p><strong>白石：</strong>タスク管理は何を使ってます？</p>

<p><strong>川田：</strong>うちのチームだと、タスク管理はカンバン。ToDoリストとしてざっくりタスクをポストイットで並べてます。トラブルがあったらそっちを優先したり、技術的な問題で遅れることもあります。タスクも今まで見てきた中ではわりと独立性が高いとおもってて、エンジニアやデザイナー、ディレクターやサポート担当者など、全員にビルド/デプロイ権限があって、自分たちが主体になってデプロイにまでもっていく。とはいえ、リーダーが責任をとるとか、デプロイした人が責任をとるとかそういうものもなく、リスクはチーム全体でうまく運用方法を改善しながらカバーしていきます。</p>

<p><img src="/wp-content/uploads/2015/11/DSC08778.jpg" alt="" width="640" height="440" class="aligncenter size-full wp-image-17653" srcset="/wp-content/uploads/2015/11/DSC08778.jpg 640w, /wp-content/uploads/2015/11/DSC08778-300x206.jpg 300w, /wp-content/uploads/2015/11/DSC08778-207x142.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>細かい機能とかコードレベルの話はGitHubです。プライベートのリポジトリ上に、Issue立てたり、PullRequest作ってMergeして、みたいなかんじです。よくあるGitHubの普通な運用方法になるとおもいます。</p>

<p>想いとか、こうやったほうがいいというポエムは<a href="https://esa.io/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">esa</a>、具体的なのはGitHubです。全体像はカンバンで、普段のコミュニケーションはidobataがメインです。</p>

<p><img src="/wp-content/uploads/2015/11/DSC08779.jpg" alt="" width="640" height="429" class="aligncenter size-full wp-image-17654" srcset="/wp-content/uploads/2015/11/DSC08779.jpg 640w, /wp-content/uploads/2015/11/DSC08779-300x201.jpg 300w, /wp-content/uploads/2015/11/DSC08779-207x139.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p><strong>白石：</strong>ほかに開発体制で面白いトピックはありますか？</p>

<p><strong>川田：</strong>開発体制とは違うかもしれないんですけど、前の会社ではコミュニケーション手段がほぼメールと電話だけだったんです。それがこの会社に来てからは、メールと電話は一切使ったことがない。一度もです。ツールをしっかり固めて、コミュニケーションコストを下げると、得られる情報量が大きくなって、結果としてチームを超えていろんな情報にアクセスできるんです。ツールひとつで、ここまで組織がフラットになれるものなんですね。</p>

<p>ただ一方で、まずいと思うところもあって。メールや電話といったツールは、一般的なビジネスでは必須のコミュニケーションツールですよね。オーバーヘッドはとてつもなく大きいのですが、使わなくなるとそれはそれで、マナーやルールがわからなくなって社会から取り残されていく不安も感じるんです。両方のバランスが重要と感じています。</p>

<p><strong>白石：</strong>社員同士のやりとりは何を使ってるんですか？</p>

<p><strong>川田：</strong>一部はSkypeですが、基本はidobataでオープンにしてます。idobataのタイムライン上には、社員同士のやりとりだけじゃなく、自動的にデプロイの情報が流れてきたり、サポートの状況とかが流れてきたりで、社員同士のやりとりが発生しやすいというかんじがしています。</p>

<h2>インフラはコンシューマ向きの超安いサーバー？</h2>

<p><strong>白石：</strong>開発環境はどうですか？</p>

<p><strong>川田：</strong>開発環境の話だと、うちにはちょっとした特殊なインフラがありまして。初期のpixivは社長が借金をして買ってきた大量のサーバーがあるのですが。コンシューマー向けの安いマザーボードを、ラックにくくりつけて使ってるんですよ。ほんとうにむき出しのままなんです(笑)。</p>

<p><img src="/wp-content/uploads/2015/11/DSC08793.jpg" alt="" width="640" height="412" class="aligncenter size-full wp-image-17658" srcset="/wp-content/uploads/2015/11/DSC08793.jpg 640w, /wp-content/uploads/2015/11/DSC08793-300x193.jpg 300w, /wp-content/uploads/2015/11/DSC08793-207x133.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>さすがに今は本番環境をデータセンターに預けるようにしていますが、開発環境には未だにそのマザーボードむき出しのサーバーをインフラとして使ってるんです。インフラチームの図画工作スキルは、いまだに高いようですね(笑)。</p>

<p>インフラの話をもう少し突っ込んですると、pixivの場合はサービスの特性上、クラウドよりオンプレのほうが向いていてそっちが中心ですね。とはいえ、ところどころにクラウドは使われていて、新しいプロジェクトだとAWSみたいなクラウドも使われています。</p>

<p>データベースは、基本的にはMySQL使ってます。OSはLinux。新しいプロジェクトはRails使うことが多いんですが、「Rails最強!! Railsじゃないとダメだ！」みたいな人はいなくて、ツールとして使っているという印象です。</p>

<h2>サービスはリリースした時の最新技術で</h2>

<p><strong>白石：</strong>HTML5 Experts.jpはフロントエンド開発者が主な読者なので、フロントエンド開発の話も聞かせてもらえますか？</p>

<p><strong>川田：</strong>私が関わるBOOTHだと、マークアップはSlim、CSSはSASSやCoffeeScriptとか。Ruby書いている人にやりやすい環境で整っています。また、開発したのが2013年なので、CoffeeScript、Backbone.js、Marionette.jsなどを使ってます。いまだとReactあたりがもっと上手く問題を解決してくれたりするんでしょうし、SPA（Single page application）ももっといいやり方があるのでしょうが、当時の技術を使っているので…。</p>

<p>とはいえ、2007年に作られたpixivでも、CoffeeScriptが使われていたりはします。部分的に入れ替えも進んでいます。今年の6月にリリースしたお絵かきアプリ「pixiv Sketch」は、React.jsやBabelが使われています。もろ時代の影響を受けていますね。</p>

<p><strong>白石：</strong>それだけフロントエンドの流れが早いってことですね。</p>

<p>フロントエンドだと、そこそこエッジな事例がきけそうな、pixiv Sketchのエンジニアを呼んでみますね。</p>

<h2>ReactとFluxでサーバーサイドレンダリング</h2>

<p>──ということで、geta6さんにご登場いただきました。</p>

<p><strong>geta6：</strong>片倉@geta6です。「pixiv Sketch」の担当エンジニアをしています。</p>

<p><strong>白石：</strong>ぜひ、フレームワーク周りで面白い話を聞かせてください。</p>

<p><strong>geta6：</strong>ブラウザ版のpixiv Sketchは、Node.js上で動かしています。</p>

<p><img src="/wp-content/uploads/2015/11/DSC08807.jpg" alt="" width="640" height="438" class="aligncenter size-full wp-image-17737" srcset="/wp-content/uploads/2015/11/DSC08807.jpg 640w, /wp-content/uploads/2015/11/DSC08807-300x205.jpg 300w, /wp-content/uploads/2015/11/DSC08807-207x142.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /><span style="font-size: 80%"><strong>　　▲ピクシブ株式会社　エンジニア　片倉弘貴さん</strong><br></span></p>

<p><strong>白石：</strong>Node.jsってことは、サーバーサイドから全然違うかんじなんでしょうか。</p>

<p><strong>geta6：</strong>サーバーサイドは、RailsによるAPIサーバーと、Node.jsによるレンダリングサーバーで構成されていて。前者はgrapeを使用していてviewを持たずJSONしか吐かない仕様になっていて、後者はサーバーサイドでAPIを叩いてDOMを構築するReactサーバーになっています。</p>

<p><strong>白石：</strong>なるほど。最近、Universal JavaScriptととも言われているIsomorphic Javascriptですね。それでサーバーサイドレンダリングしてるって、まさに最新ですね。</p>

<p><strong>geta6：</strong>フレームワークは、Yahooさんが作ったfluxibleというのを使っています。サーバーとクライアントが同じコードで動くので、キツイ面もありますけど。</p>

<p><strong>白石：</strong>fluxibleって、結構ヘビーだって聞きますね。</p>

<p><strong>geta6：</strong>fluxibleは一人でさくっと開発する場合とか、SPA（シングルページアプリケーション）とかには向いてないかもしれません。ただ、pixiv Sketchみたいに複数人数で開発する場合は、ある程度がっつりしたコードを書けるし、メンテナビリティがあるので魅力的です。</p>

<p>良いところは、二重実装をしなくていいことですね。テンプレートをslim側で書いて、Backbone.jsからもってきて、Javascriptテンプレート内にテキストテンプレートをもう一個書いて…とか面倒なことはしなくていい。同じコードベースでAPIのリクエストとかすべてのことができるので、そこが便利です。</p>

<p><strong>白石：</strong>サーバーとクライアントが同じコードで動くのがキツイと言ってましたが、具体的にはどんなところが大変なんですか？</p>

<p><strong>geta6：</strong>Reactは、クライアント側の世界とサーバー側の世界で、呼ばれるメソッドが違うところがあるんです。componentDidMountっていうメソッドなんですが、それはクライアント側にしか呼ばれないので、その中ではCanvasの操作やDOMの操作が書けるんです。それがわかっていればそんなにつらくないけど、React始めたばかりだと、その辺がわからないのでつらいのかもしれないです。</p>

<p><strong>白石：</strong>getaさんの勉強量は相当すごそうですね。</p>

<p><strong>geta6：</strong>いつもはそんなに勉強はしてないんですけど、pixiv Sketch始めるときに、Reactが流行ってるって聞いて、どうしてもやりたいって言ったら採用されたんです。React全然知らなかったのに、採用されたので一から徹底的に勉強しました(笑)。</p>

<p><img src="/wp-content/uploads/2015/11/DSC08863.jpg" alt="" width="640" height="406" class="aligncenter size-full wp-image-17744" srcset="/wp-content/uploads/2015/11/DSC08863.jpg 640w, /wp-content/uploads/2015/11/DSC08863-300x190.jpg 300w, /wp-content/uploads/2015/11/DSC08863-207x131.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<h2>課題はパフォーマンス改善。野望はES6への乗り換え</h2>

<p><strong>白石：</strong>お二人が、今課題だと思ってることってありますか。</p>

<p><strong>川田：</strong>まだ入社したばかりなので、あまり深く掴めていませんが。自分の関わっているサービスのパフォーマンスが悪いことが気になっていますね。RailsとかJavaScriptとか、いろんなところに悪さするのが潜んでいますね。</p>

<p>もう一つは闇のコードたち。締め切り間際で、アドホックに作りこんじゃったコードとかがたくさんありまして。たとえば、BOOTHは「<a href="https://booth.pm/apollo/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">APOLLO(アポロ)</a>」という同人音楽をネット上で頒布する即売会イベントを開いていて、そういうイベント対応のために作りこまれて、めったに呼ばれないメンテされにくい闇のコードが眠っているんです。ある日とつぜん爆発しそうなので、なんとか阻止したいです。すでに若干、爆発しかけていますが…</p>

<p>こういう、サービス固有の問題みたいなのは山程ありますが、それ以外はとくに不安を感じてはいません。テストコードも書かれているし、最新のバージョンに上げていきましょうというモチベーションもある。機能追加や改善ばかりな企画屋さんがいるチームは世の中にいっぱいいるけど、うちはコードヘルスがサービスのライフサイクルやセキュリティにどんな影響を与えるのか理解されているし、バージョンアップしておかないと大変という感覚とか、エンジニアならわかる勘所を大事にしてくれています。上手くやれている感じがしています。</p>

<p><strong>白石：</strong>今後チャレンジしたいことはどうでしょう。</p>

<p><strong>川田：</strong>やっぱり、早くES6にしたいです。CoffeeScriptやめたい(笑)。</p>

<p><strong>白石：</strong>でも、CoffeeScriptのほうが言語的な機能は上じゃないですか？</p>

<p><strong>geta6：</strong>CoffeeScriptって1週間前に書いた自分のコードが読めなくなるんですよ。言語機能が強すぎて。特殊な記法が必要だし。ES6では普通に読めるから、メンテナンス性は高いですよね。</p>

<p><strong>川田：</strong>CoffeeScriptって、少し大きくなってくると、ビルドした結果を想像しながら書かなきゃいけなくなることがある。Devツールで、ちょっとこの値どうなってるんだろうとかコンソールを叩き始めると、今までCoffeeScriptのコードを読んでたはずなのに、完全にJavaScriptに戻ってたり。</p>

<p><strong>geta6：</strong>CoffeeScript書いてるより、JavaScript書いてるかんじが強いんですよね。インデントが効かないのも厳しい(笑)。</p>

<p><strong>川田：</strong>そうなんです。以前、私はTypeScriptを使っていたんですが、あれはビルドした結果がストレートに想像できるのがいい。あと、将来を見据えるとやっぱりES6を推しちゃいますね。</p>

<p><img src="/wp-content/uploads/2015/11/DSC08857.jpg" alt="" width="640" height="438" class="aligncenter size-full wp-image-17747" srcset="/wp-content/uploads/2015/11/DSC08857.jpg 640w, /wp-content/uploads/2015/11/DSC08857-300x205.jpg 300w, /wp-content/uploads/2015/11/DSC08857-207x142.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<h2>Nodeのデプロイツールに定番がほしい</h2>

<p><strong>白石：</strong>getaさんはどうですか？</p>

<p><strong>geta6：</strong>開発環境の課題は、Node.jsのデプロイツールとプロセスマネージャーに定番がないことですね。デプロイは、信頼性をとってcapistranoを使ってるんですよ。Nodeのデプロイツールはどれも機能が貧弱で手数も多いので、定番でいいのが出てこないかなって思ってます。</p>

<p><strong>白石：</strong>プロセスマネージャーは何を使ってるんですか？</p>

<p><strong>geta6：</strong>プロセスマネージャーはPM2を使ってます。capistranoからシンボリックリンク設置して、currentで新しいファイルをディレクトリに送るんですが、Nodeのファイルシステムが変わってから、シンボリックリンクを追跡して、デプロイ前のファイルのところで監視しちゃうようになったんです。そこでプロセスマネージャーが生きちゃってるので、デプロイしてもファイルが新しくならないんです。そこで一回殺すというのをやってるので、ダウンタイムが若干できてしまうっていう問題点があります。</p>

<p><strong>白石：</strong>そういった課題の改善に取り組んでいるんですね。次にチャレンジしたいことはありますか？</p>

<p><strong>geta6：</strong>API側はバックエンドのプロセスマネージャーがUnicornなんですけど、ラインがN個しかなくて、同時に来ちゃったらつまっちゃうんです。Node側でいいかんじでリクエストをバッファリングしてうまく送れないかと。受付サーバーをNodeにしてゆっくり流すというようなことをしたいです。</p>

<p><strong>白石：</strong>なかなかエッジなプロジェクトになりそうですね。</p>

<p><img src="/wp-content/uploads/2015/11/DSC08859.jpg" alt="" width="640" height="394" class="aligncenter size-full wp-image-17749" srcset="/wp-content/uploads/2015/11/DSC08859.jpg 640w, /wp-content/uploads/2015/11/DSC08859-300x185.jpg 300w, /wp-content/uploads/2015/11/DSC08859-207x127.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p><strong>geta6：</strong>requestIdleCallBackだっけ？あれも何かやってみたい。</p>

<p><strong>川田：</strong>ピクシブで「<a href="https://tokyo-web-perf.doorkeeper.jp/events/30701" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">東京 Web Performance</a>」という濃い勉強会をやったんですけど、エッジすぎて人が集まらないかなと思ったら、エッジな人が結構集まってきて(笑)。第一回は「requestIdleCallback」を味見したんですが、広告やアナリティクスに割といいかんじで使えそうだったんで、全力で攻めるんじゃないかって話をしてました。ピクシブに思いのほか、いい影響を及ぼしそうな予感がしてます。</p>

<p><strong>白石：</strong>じゃあ、そこも次のチャレンジになりそうですね。今日は面白いお話を聞かせていただき、ありがとうございました。</p>

<p><img src="/wp-content/uploads/2015/11/DSC08876.jpg" alt="" width="640" height="448" class="aligncenter size-full wp-image-17736" srcset="/wp-content/uploads/2015/11/DSC08876.jpg 640w, /wp-content/uploads/2015/11/DSC08876-300x210.jpg 300w, /wp-content/uploads/2015/11/DSC08876-207x145.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>
]]></content:encoded>
			</item>
		<item>
		<title>乗るしかない！Reactのビッグウェーブに！─isomorphic tokyo meetupに参加してきた</title>
		<link>/shumpei-shiraishi/14895/</link>
		<pubDate>Fri, 01 May 2015 03:01:33 +0000</pubDate>
		<dc:creator><![CDATA[白石 俊平]]></dc:creator>
				<category><![CDATA[最新動向]]></category>
		<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[システム開発]]></category>
		<category><![CDATA[AngularJS]]></category>
		<category><![CDATA[Fetcr]]></category>
		<category><![CDATA[Flatiron]]></category>
		<category><![CDATA[Flummox]]></category>
		<category><![CDATA[Flux]]></category>
		<category><![CDATA[Fluxible]]></category>
		<category><![CDATA[React]]></category>
		<category><![CDATA[Rendr]]></category>
		<category><![CDATA[Virtual DOM]]></category>
		<category><![CDATA[isomorphic]]></category>
		<category><![CDATA[アーキテクチャ]]></category>

		<guid isPermaLink="false">/?p=14895</guid>
		<description><![CDATA[連載： アプリケーションアーキテクチャ最前線 (1)おはようございます。編集長の白石です。 昨日（2015年4月30日）、isomorphic tokyo meetupに参加してきました。 というのも実は近々、HTML5...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/arch/" class="series-287" title="アプリケーションアーキテクチャ最前線" data-wpel-link="internal">アプリケーションアーキテクチャ最前線</a> (1)</div><p>おはようございます。編集長の白石です。</p>

<p>昨日（2015年4月30日）、<a href="http://nodejs.connpass.com/event/13363/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">isomorphic tokyo meetup</a>に参加してきました。</p>

<p>というのも実は近々、HTML5 Experts.jpでは「Webアプリケーション・アーキテクチャ」に関する特集を行う予定なのですが、そこでキーワードとして挙げられていたのが<strong>isomorphic。</strong>
サーバサイドとクライアントサイドでコードの共有を促進するのが主な目的の一つ、というところまでは理解できたのですが、実際のところ、アーキテクチャはどう変わるのか？
それを探りたいと思っていたところ、ちょうどよくイベントの開催がアナウンスされていたので、急遽取材させていただきました。</p>

<p>取材を快く受け入れてくださった、主催の<a href="https://twitter.com/yosuke_furukawa" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Yosuke FURUKAWA</a>さん、本当にありがとうございました。</p>

<p>この記事では、トップバッターで講演されていた<a href="https://twitter.com/koichik" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">koichik</a>さんの講演内容を中心にご紹介して、isomorphicに触れるきっかけとなる記事を目指します。</p>

<p>なお、本日の講演者の皆様による資料はこちらになります。</p>

<h2><a href="http://nodejs.connpass.com/event/13363/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">isomorphic tokyo meetup</a>の発表資料</h2>

<h3>「Isomorphic Survival Guide」(by <a href="https://twitter.com/koichik" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">koichik</a>)</h3>

<p><a class="embedly-card" href="https://speakerdeck.com/koichik/isomorphic-survival-guide" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Isomorphic Survival Guide</a>
<script async src="//cdn.embedly.com/widgets/platform.js" charset="UTF-8"></script></p>

<h3>「Isomorphic Web development with Scala &amp; Scala.js」(by <a href="https://twitter.com/TanUkkii007" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">TanUkkii</a>)</h3>

<p><a class="embedly-card" href="http://www.slideshare.net/TanUkkii/isomorphic-web-development-with-scala-and-scalajs" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Isomorphic web development with scala and scala.js</a>
<script async src="//cdn.embedly.com/widgets/platform.js" charset="UTF-8"></script></p>

<h3>「実践isomorphic (+ Electron)」(by <a href="https://twitter.com/mizchi" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">mizchi</a>)</h3>

<p><a class="embedly-card" href="https://speakerdeck.com/mizchi/shi-jian-isomorphic-plus-electron" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">実践Isomorphic(+ Electron)</a>
<script async src="//cdn.embedly.com/widgets/platform.js" charset="UTF-8"></script></p>

<h3>「Unified Interface on Isomorphic JavaScript」 (by <a href="https://twitter.com/axross_" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">axross</a>)</h3>

<p><a class="embedly-card" href="http://www.slideshare.net/axross/unified-interface-on-isomorphic-javascript" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Unified Interface on Isomorphic Javascript</a>
<script async src="//cdn.embedly.com/widgets/platform.js" charset="UTF-8"></script></p>

<h3>「やみくも isomorphic から抜け出すために足りてないもの」 (by <a href="http://twitter.com/Jxck_" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Jxck_</a>)</h3>

<p>※資料は後日公開だそうです。</p>

<blockquote class="twitter-tweet" lang="ja"><p lang="ja" dir="ltr">今日のスライドがちょっと片手間すぎるので、公開はいろいろ直してからにします。 <a href="https://twitter.com/hashtag/isomorphic_meetup?src=hash" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">#isomorphic_meetup</a></p>&mdash; Jxck (@Jxck_) <a href="https://twitter.com/Jxck_/status/593792866075353088" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">2015, 4月 30</a></blockquote>

<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

<h2>koichikさんによる「Isomorphic Survival Guide」つまみ食いレポート</h2>

<p><a href="https://twitter.com/koichik" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">koichik</a>さんの「Isomorphic Survival Guide」は、まずIsomorphicという言葉の語源からでした。ギリシャ語で「同じ」という意味を表す「isos」という言葉と、「形」という意味を表す「morphe」という言葉を合わせたものだそうです。</p>

<div id="attachment_14897" style="width: 650px" class="wp-caption aligncenter"><a href="https://html5experts.jp/wp-content/uploads/2015/05/01_isomorphic.jpg" data-wpel-link="internal"><img src="/wp-content/uploads/2015/05/01_isomorphic-640x480.jpg" alt="isomorphicの語源" width="640" height="480" class="size-large wp-image-14897" srcset="/wp-content/uploads/2015/05/01_isomorphic.jpg 640w, /wp-content/uploads/2015/05/01_isomorphic-300x225.jpg 300w, /wp-content/uploads/2015/05/01_isomorphic-207x155.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></a><p class="wp-caption-text">isomorphicの語源</p></div>

<p>同じ成り立ちの言葉として、「metamorphic」や「polymorphic」があるとのこと。オブジェクト指向の世界で頻繁に用いられる「ポリモーフィック」という言葉が、isomorphicと同様「-morphic」で終わる単語だと気づいたのはこの時が初めてで、ハッとしました。</p>

<div id="attachment_14898" style="width: 650px" class="wp-caption aligncenter"><a href="https://html5experts.jp/wp-content/uploads/2015/05/02_x-morphic.jpg" data-wpel-link="internal"><img src="/wp-content/uploads/2015/05/02_x-morphic-640x480.jpg" alt="&quot;-morphic&quot;で終わる言葉はほかにも" width="640" height="480" class="size-large wp-image-14898" srcset="/wp-content/uploads/2015/05/02_x-morphic.jpg 640w, /wp-content/uploads/2015/05/02_x-morphic-300x225.jpg 300w, /wp-content/uploads/2015/05/02_x-morphic-207x155.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></a><p class="wp-caption-text">&#8220;-morphic&#8221;で終わる言葉はほかにも</p></div>

<p>で、isomorphicが語られるときには、「クライアントとサーバの間でのコード共有」や「フロントエンドとバックエンドの間でのコード共有」と紹介されることが多いですが、そもそもクライアントとフロントエンド、サーバとバックエンドが同じ意味の単語なのか、そこには人による解釈の違いもあれば、指している意味合いの違いもある、と指摘。</p>

<div id="attachment_14899" style="width: 650px" class="wp-caption aligncenter"><a href="https://html5experts.jp/wp-content/uploads/2015/05/03_2x2.jpg" data-wpel-link="internal"><img src="/wp-content/uploads/2015/05/03_2x2-640x480.jpg" alt="クライアント・サーバという用語とフロントエンド・バックエンドという用語は同一ではない" width="640" height="480" class="size-large wp-image-14899" srcset="/wp-content/uploads/2015/05/03_2x2.jpg 640w, /wp-content/uploads/2015/05/03_2x2-300x225.jpg 300w, /wp-content/uploads/2015/05/03_2x2-207x155.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></a><p class="wp-caption-text">クライアント・サーバという用語とフロントエンド・バックエンドという用語は同一ではない</p></div>

<p>この講演においては、クライアントとサーバはネットワークの「こちら側」と「あちら側」、フロントエンドとバックエンドは情報の入出力を「人間相手に行う」のか「ストレージ相手に行う」のか、という意味で取り扱う。</p>

<div id="attachment_14900" style="width: 650px" class="wp-caption aligncenter"><a href="https://html5experts.jp/wp-content/uploads/2015/05/04_definition.jpg" data-wpel-link="internal"><img src="/wp-content/uploads/2015/05/04_definition-640x480.jpg" alt="本講演における用語の定義" width="640" height="480" class="size-large wp-image-14900" srcset="/wp-content/uploads/2015/05/04_definition.jpg 640w, /wp-content/uploads/2015/05/04_definition-300x225.jpg 300w, /wp-content/uploads/2015/05/04_definition-207x155.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></a><p class="wp-caption-text">本講演における用語の定義</p></div>

<p>例えば90年ごろの「C/Sシステム」（いわゆる「クラサバ」）は、クライアントのWindowsマシン上で「人間向け」（フロントエンド）の処理も「ストレージ向け」（バックエンド）の処理も行われていました。このように、クライアント＝フロントエンド、サーバ＝バックエンドという対応関係は時代によって変遷してきており、J2EEが提唱した三層アーキテクチャやRIAなど、様々なアーキテクチャと製品が模索されてきました。</p>

<div id="attachment_14901" style="width: 650px" class="wp-caption aligncenter"><a href="https://html5experts.jp/wp-content/uploads/2015/05/05_cs.jpg" data-wpel-link="internal"><img src="/wp-content/uploads/2015/05/05_cs-640x480.jpg" alt="C/Sシステム" width="640" height="480" class="size-large wp-image-14901" srcset="/wp-content/uploads/2015/05/05_cs.jpg 640w, /wp-content/uploads/2015/05/05_cs-300x225.jpg 300w, /wp-content/uploads/2015/05/05_cs-207x155.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></a><p class="wp-caption-text">C/Sシステム</p></div>

<div id="attachment_14902" style="width: 650px" class="wp-caption aligncenter"><a href="https://html5experts.jp/wp-content/uploads/2015/05/06_bbff.jpg" data-wpel-link="internal"><img src="/wp-content/uploads/2015/05/06_bbff-640x480.jpg" alt="フロントエンドとバックエンドの変遷" width="640" height="480" class="size-large wp-image-14902" srcset="/wp-content/uploads/2015/05/06_bbff.jpg 640w, /wp-content/uploads/2015/05/06_bbff-300x225.jpg 300w, /wp-content/uploads/2015/05/06_bbff-207x155.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></a><p class="wp-caption-text">フロントエンドとバックエンドの変遷</p></div>

<h2>isomorphicに挑戦してきた様々なフレームワーク</h2>

<p>こうした中、少しでも開発から無駄をなくすために、クライアント／サーバ、フロントエンド／バックエンドの間でコードを共有できないかという可能性が探られてきました。</p>

<p>「isomorphic」という単語は、筆者としては最近になって聞くようになったのですが、実は2011年にリリースされた
「<a href="http://flatironjs.org/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Flatiron</a>」というフレームワークが提唱した概念だったそうです。4年近くも前から使われていた用語だったのですね。</p>

<div id="attachment_14903" style="width: 650px" class="wp-caption aligncenter"><a href="https://html5experts.jp/wp-content/uploads/2015/05/07_flatiron.jpg" data-wpel-link="internal"><img src="/wp-content/uploads/2015/05/07_flatiron-640x480.jpg" alt="Flatiron" width="640" height="480" class="size-large wp-image-14903" srcset="/wp-content/uploads/2015/05/07_flatiron.jpg 640w, /wp-content/uploads/2015/05/07_flatiron-300x225.jpg 300w, /wp-content/uploads/2015/05/07_flatiron-207x155.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></a><p class="wp-caption-text">Flatiron</p></div>

<p>しかし、Flatironはそれほど普及することなく現在に至ります。その後もYahoo!の「<a href="https://github.com/yahoo/mojito" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Mojito</a>」や、一時期大きな話題になった（今でもアクティブに開発されていますが）<a href="https://www.meteor.com/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Meteor</a>など、様々なプロダクトがisomorphicなアプローチにチャレンジしてきました。しかしこれらがあまり大きく普及しなかった要因は、「（プロダクト利用者にとっての）どんな課題を解くのか」が不明瞭だったり、ニッチ過ぎたり、先進的すぎたりしたことにあると指摘。</p>

<div id="attachment_14904" style="width: 650px" class="wp-caption aligncenter"><a href="https://html5experts.jp/wp-content/uploads/2015/05/08_frameworks.jpg" data-wpel-link="internal"><img src="/wp-content/uploads/2015/05/08_frameworks-640x480.jpg" alt="どんな課題を解くのかが重要" width="640" height="480" class="size-large wp-image-14904" srcset="/wp-content/uploads/2015/05/08_frameworks.jpg 640w, /wp-content/uploads/2015/05/08_frameworks-300x225.jpg 300w, /wp-content/uploads/2015/05/08_frameworks-207x155.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></a><p class="wp-caption-text">どんな課題を解くのかが重要</p></div>

<p>そんな中、<a href="https://www.airbnb.jp/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Airbnb</a>が2013年に公開した「<a href="https://github.com/rendrjs/rendr" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Rendr</a>」
は、SPA (Single Page Application)の「初期表示が遅い」「SEOが弱い」という課題を解決すべく生み出されたもので、
かなり実用的でした。</p>

<div id="attachment_14905" style="width: 650px" class="wp-caption aligncenter"><a href="https://html5experts.jp/wp-content/uploads/2015/05/09_rendr.jpg" data-wpel-link="internal"><img src="/wp-content/uploads/2015/05/09_rendr-640x480.jpg" alt="Rendr(Airbnb)" width="640" height="480" class="size-large wp-image-14905" srcset="/wp-content/uploads/2015/05/09_rendr.jpg 640w, /wp-content/uploads/2015/05/09_rendr-300x225.jpg 300w, /wp-content/uploads/2015/05/09_rendr-207x155.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></a><p class="wp-caption-text">Rendr(Airbnb)</p></div>

<p>RendrはBackbone.jsを拡張してisomorphicな環境を実現するものでした。Rendrは、以下のように様々な可能性を切り開きました。</p>

<ul>
<li>サーバサイドにおけるフロントエンドレイヤをJavaScriptで提供することで、クライアントとサーバのコード共有を実現しやすい</li>
<li>サーバサイドにおけるフロントエンドレイヤがセッション管理を行うことで、バックエンドのAPIをステートレスに保つことができる</li>
<li>サーバサイドにおけるフロントエンドレイヤがAPIゲートウェイとしてデータ変換を行ったり、様々なバックエンドAPIを組み合わせて
フロントエンドに提供する（オーケストレーション）ことを可能にする</li>
<li>上記のことから、（サーバサイドにおける）フロントエンドとバックエンドの疎結合な関係や、バックエンドの実装をJavaScript
に縛られず自由に開発できるようになり、ステートレスなマイクロサービスが協調して一つのサービスを作り上げるという構成を構築しやすい</li>
</ul>

<div id="attachment_14906" style="width: 650px" class="wp-caption aligncenter"><a href="https://html5experts.jp/wp-content/uploads/2015/05/10_rendr-isomorphic.jpg" data-wpel-link="internal"><img src="/wp-content/uploads/2015/05/10_rendr-isomorphic-640x480.jpg" alt="Rendr的なIsomorphicの可能性" width="640" height="480" class="size-large wp-image-14906" srcset="/wp-content/uploads/2015/05/10_rendr-isomorphic.jpg 640w, /wp-content/uploads/2015/05/10_rendr-isomorphic-300x225.jpg 300w, /wp-content/uploads/2015/05/10_rendr-isomorphic-207x155.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></a><p class="wp-caption-text">Rendr的なIsomorphicの可能性</p></div>

<h2>Reactの波に乗れ！</h2>

<p>ですが、Rendrがリリースされた時期はAngularJSが人気を獲得した時期と重なっており、残念ながら大きな話題にはなりませんでした…。しかし今、「仮想DOM」というキャッチーなキーワードを引っさげ、<a href="https://facebook.github.io/react/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">React</a>が登場するや、非常な人気を博して今に至ります。</p>

<div id="attachment_14907" style="width: 650px" class="wp-caption aligncenter"><a href="https://html5experts.jp/wp-content/uploads/2015/05/11_react.jpg" data-wpel-link="internal"><img src="/wp-content/uploads/2015/05/11_react-640x480.jpg" alt="Reactの仮想DOM" width="640" height="480" class="size-large wp-image-14907" srcset="/wp-content/uploads/2015/05/11_react.jpg 640w, /wp-content/uploads/2015/05/11_react-300x225.jpg 300w, /wp-content/uploads/2015/05/11_react-207x155.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></a><p class="wp-caption-text">Reactの仮想DOM</p></div>

<p>しかしReactはあくまでビューだけに特化したライブラリ。アプリケーションアーキテクチャとしては、Facebookが
「<a href="https://github.com/facebook/flux" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Flux</a>」を提唱していますが、公式な実装が提供されたのはFluxの一部分
のみであったため、独自実装が乱立する事態となっています。</p>

<div id="attachment_14908" style="width: 650px" class="wp-caption aligncenter"><a href="https://html5experts.jp/wp-content/uploads/2015/05/12_flux.jpg" data-wpel-link="internal"><img src="/wp-content/uploads/2015/05/12_flux-640x480.jpg" alt="Flux" width="640" height="480" class="size-large wp-image-14908" srcset="/wp-content/uploads/2015/05/12_flux.jpg 640w, /wp-content/uploads/2015/05/12_flux-300x225.jpg 300w, /wp-content/uploads/2015/05/12_flux-207x155.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></a><p class="wp-caption-text">Flux</p></div>

<p>Fluxを用いたアプリの基本的な構成は以下のようになります。
フロントエンド部分に限ってみると、処理の流れが綺麗に一方向（unidirectional）になっているのがわかります。</p>

<div id="attachment_14909" style="width: 650px" class="wp-caption aligncenter"><a href="https://html5experts.jp/wp-content/uploads/2015/05/13_fluxapp.jpg" data-wpel-link="internal"><img src="/wp-content/uploads/2015/05/13_fluxapp-640x480.jpg" alt="Flux的アプリの基本要素" width="640" height="480" class="size-large wp-image-14909" srcset="/wp-content/uploads/2015/05/13_fluxapp.jpg 640w, /wp-content/uploads/2015/05/13_fluxapp-300x225.jpg 300w, /wp-content/uploads/2015/05/13_fluxapp-207x155.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></a><p class="wp-caption-text">Flux的アプリの基本要素</p></div>

<p>そして何よりReactが期待されているのは、仮想DOMの仕組みを応用したisomorphicなアーキテクチャ。クライアントでは仮想DOMを実際のDOMツリーに変換しますが、サーバサイドでは仮想DOMからHTML文字列を出力するようにできるので、クライアントとサーバのどちらでも同様のコードが実行できるわけです。</p>

<p>Reactに関係するisomorphicなライブラリには、以下の様なものがあります。</p>

<div id="attachment_14910" style="width: 650px" class="wp-caption aligncenter"><a href="https://html5experts.jp/wp-content/uploads/2015/05/14_react_isomorphic.jpg" data-wpel-link="internal"><img src="/wp-content/uploads/2015/05/14_react_isomorphic-640x480.jpg" alt="Reactに関係した、Isomorphicなライブラリ" width="640" height="480" class="size-large wp-image-14910" srcset="/wp-content/uploads/2015/05/14_react_isomorphic.jpg 640w, /wp-content/uploads/2015/05/14_react_isomorphic-300x225.jpg 300w, /wp-content/uploads/2015/05/14_react_isomorphic-207x155.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></a><p class="wp-caption-text">Reactに関係した、Isomorphicなライブラリ</p></div>

<p><a href="https://github.com/acdlite/flummox/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Flummox</a>も期待のライブラリ。</p>

<div id="attachment_14911" style="width: 650px" class="wp-caption aligncenter"><a href="https://html5experts.jp/wp-content/uploads/2015/05/15_flummox.jpg" data-wpel-link="internal"><img src="/wp-content/uploads/2015/05/15_flummox-640x480.jpg" alt="Flummox" width="640" height="480" class="size-large wp-image-14911" srcset="/wp-content/uploads/2015/05/15_flummox.jpg 640w, /wp-content/uploads/2015/05/15_flummox-300x225.jpg 300w, /wp-content/uploads/2015/05/15_flummox-207x155.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></a><p class="wp-caption-text">Flummox</p></div>

<p>Yahoo!が開発中の<a href="https://github.com/yahoo/fluxible" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Fluxible</a>は、比較的重量級なアプローチの、isomorphicなFluxアプリケーションコンテナ。</p>

<div id="attachment_14912" style="width: 650px" class="wp-caption aligncenter"><a href="https://html5experts.jp/wp-content/uploads/2015/05/16_fluxible.jpg" data-wpel-link="internal"><img src="/wp-content/uploads/2015/05/16_fluxible-640x480.jpg" alt="Fluxible" width="640" height="480" class="size-large wp-image-14912" srcset="/wp-content/uploads/2015/05/16_fluxible.jpg 640w, /wp-content/uploads/2015/05/16_fluxible-300x225.jpg 300w, /wp-content/uploads/2015/05/16_fluxible-207x155.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></a><p class="wp-caption-text">Fluxible</p></div>

<p>Fluxibleが使用する「<a href="https://github.com/yahoo/fetchr" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Fetchr</a>」は、バックエンド（の窓口となるWeb API）へのアクセスを、クライアントサイドとサーバサイドで同様のコードを用いることを実現します。正しくセットアップしていれば、Fluxアプリケーションのisomorphic化を促進できると期待されています。</p>

<div id="attachment_14913" style="width: 650px" class="wp-caption aligncenter"><a href="https://html5experts.jp/wp-content/uploads/2015/05/17_fetchr.jpg" data-wpel-link="internal"><img src="/wp-content/uploads/2015/05/17_fetchr-640x480.jpg" alt="Fetchr" width="640" height="480" class="size-large wp-image-14913" srcset="/wp-content/uploads/2015/05/17_fetchr.jpg 640w, /wp-content/uploads/2015/05/17_fetchr-300x225.jpg 300w, /wp-content/uploads/2015/05/17_fetchr-207x155.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></a><p class="wp-caption-text">Fetchr</p></div>

<h2>まとめ</h2>

<p>isomorphicなアーキテクチャは長い間模索されていましたが、これまでいまいち波に乗り切れていませんでした。しかし今はReactが非常に人気を博し、isomorphicなアーキテクチャの実現に対して、多くの人々が注力しています。</p>

<p>マイクロサービスとの相性も非常に良いと考えられ、今後大きな潮流になっていくのは間違いないでしょう。</p>

<div id="attachment_14914" style="width: 650px" class="wp-caption aligncenter"><a href="https://html5experts.jp/wp-content/uploads/2015/05/18_matome.jpg" data-wpel-link="internal"><img src="/wp-content/uploads/2015/05/18_matome-640x480.jpg" alt="まとめ" width="640" height="480" class="size-large wp-image-14914" srcset="/wp-content/uploads/2015/05/18_matome.jpg 640w, /wp-content/uploads/2015/05/18_matome-300x225.jpg 300w, /wp-content/uploads/2015/05/18_matome-207x155.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></a><p class="wp-caption-text">まとめ</p></div>

<p>Reactの波に乗り遅れるな！</p>
]]></content:encoded>
		
		<series:name><![CDATA[アプリケーションアーキテクチャ最前線]]></series:name>
	</item>
	</channel>
</rss>
