webpack + typescriptな環境でthree.jsのexampleを使う

# 概要
typescriptで書き,webpackでビルドしているプロジェクトでthree.jsを使うことになった.
その際にthree.jsの導入回りで色々と躓いたのでまとめ.

結論を先に書くと,webpackを使っているときはthreeじゃなくて[three-js](https://www.npmjs.com/package/three-js)としてnpmで引いて使うとちょっとバージョンが古いけど楽という話.

# 使うためにとりあえずやったこと
まずnpmからthree.jsを取ってくる

```bash
npm install --save-dev three
```

そしてtypescript用に型定義ファイルを用意する
幸いにも`@types`に型定義ファイルが存在するのでnpmを使ってインストールする
[Typescriptの型定義ファイルを管理するtypesパッケージについて詳細はこちら](http://qiita.com/laco0416/items/ed1aadf335f12cd3618d)

これを利用し型定義ファイルを取得する

```bash
npm install --save-dev @types/three
```

# 使ってみた
やりたいことがthetaの画像を360のパノラマビューとして表示することだったので
[【Three.js】360°パノラマビューワーを作ってグリグリ操作出来るようにした] (http://qiita.com/kingpanda/items/1c3a47765b40d6d62f46)
このあたりの記事を参考にさせていただき描画のコードを記述した.

```ts
import * as THREE from 'three';

const width = 500;
const height = 500;

// scene
const scene = new THREE.Scene();

// mesh
const geometry = new THREE.SphereGeometry(5, 60, 40);
geometry.scale(-1, 1, 1);

const material = new THREE.MeshBasicMaterial({
   map: THREE.ImageUtils.loadTexture("TESTPIC=THETA.JPG")
});

 const sphere = new THREE.Mesh(geometry, material);
 scene.add(sphere);

 //camera
 const camera = new THREE.PerspectiveCamera(75, width / height, 1, 1000);
 camera.position.set(0, 0, 0.1);
 camera.lookAt(sphere.position);

 // render
 const renderer = new THREE.WebGLRenderer();
 renderer.setSize(width, height);
 renderer.setClearColor(0x000000);
 document.getElementById("target")
    .appendChild(renderer.domElement);

 renderer.render(scene, camera);
``` 
このコードを書きとりあえず画像が表示できた.

**ここまではよかった**

# 発生した問題
このビューにエフェクトやドラッグで動かすといった機能を付けていきたくなった
three.jsのexampleに入っている物を利用して作っていく.

一般な書き方だとHTMLのScriptタグでexampleの中に含まれているOrbitControls.jsとかを取ってきて使うと説明されているが今回はwebpackでビルドしているのでその手は使いたくない.

とりあえずIDEのサジェストから型定義ファイルには`THREE.OrbitControls`が含まれていることがわかったので

```ts
const controls = new THREE.OrbitControls(camera, renderer.domElement);
const render = () => {
  requestAnimationFrame(render)
  // ゆっくり回転
  sphere.rotation.y += 0.05 * Math.PI / 180;
  renderer.render(scene, camera);
  // ドラッグで動く
  controls.update();
}
render();
```

こんな感じに動くように書いてみた.
**案の定動かない**　`THREE.OrbitControls`がないよってブラウザに怒られてしまった. three.min.jsには含まれていないのだからまぁ当然である

そこでどうやってTHREE.OrbitControlsを持ってこようかという話になる.

# three.jsのexampleに含まれるコードをimportする
実質今回記事の本題になる.
色々調べていると

http://stackoverflow.com/questions/35968047/using-webpack-threejs-examples-and-typescript

https://github.com/mrdoob/three.js/issues/9562

このようなページが引っかかってwebpackのimports-loader,exports-loaderを使うだとかいろいろ書いてある.
これに従って設定してみたがうまくいかない.

困っていたところnpmに`three`ではなく`three-js`というパッケージを見つけた
[three-js](https://www.npmjs.com/package/three-js)
どうやら拡張も含めて入っていて簡単に含めることができるよう.
今回必要だった`orbitcontrolrs`や`EffectComposer`はこれで簡単に使えそうだったのでこれを試してみる

threeを消してthree-jsを導入する

```bash
npm uninstall --save-dev three
npm install --save-dev three-js
```

[three-js](https://www.npmjs.com/package/three-js)に書いてあることに従って

```ts
const THREE = require('three-js')([
   'EffectComposer',
   'OrbitControls'
]);
```
こんな感じでEffectComposerとOrbitCOntrolsを含めてTHREEを用意する.
これでとりあえず動作した

# 結果
描画結果のスクリーショット.
![img](https://gyazo.com/f7b2f7863ae2aaba77a4ef1dc28672be.png)
Thetaの画像が表示できOrbitControlsを使ってドラッグで動かせるようになった！
あとはエフェクトを付けたりしていけばよさそう.

# まとめ
webpackでthreeのexampleのライブラリが必要になるときはnpmでthree-jsを使うと便利かも?

# 感想
途中使ってみてよく分からなかったwebpackのimports-loaderとexports-loaderって何なんだろうと思った.
調べておかなければ