TypeScript でThree.js を始める

three.js の話というよりか、
node.jsのフロントエンドの環境構築の話です。

TypeScriptでthree.js扱いたい。

JavaScriptでthree.jsを扱う事は前回出来たけど、
色々補完が効かないのも不便だし、
ゲームとか作るんだったら、型を使ってラクにコーディングしたいもんですよね。

という事で、TypeScript使いましょう♪

ツールがいっぱい

node.jsのタスクランナーや、フロントエンド用のパッケージャー、TypeScriptについてなど、
本当に関係してるツールが多過ぎて…。
一体どれを使ったらいいんだと今週は途方に暮れておりました。

ただ、俺はTypeScriptでコーディングしたいだけなんだ…涙。

そんな思いを胸に、ネットサーフィンして
gulp, grunt はもう要らない子なのね。
tsd, typingsは、npmの@types に移行したのかとか。
browserify よりは、webpack2が最近主流だとか

Browserify と webpack2 調べてみた結果、
Typescriptの面倒も見てくれるので、
webpack2を使う事にしました。

もう2016年の記事ですら古い情報みたいで
なんと移り変わりの早い事よ…。

おお神よ…

これでいいんじゃない?

自分の中で理解しやすいレベルの
フロントエンド用の初期構成、ここから始めれば的な構成を共有しておこうと思う。(2017年03月の気持ち)

インストールするもの

node.js / npm はインストールされているものとして

# npm のバージョン は上げておきましょう。
npm --version
npm install -g npm

npm install で入れておくものは以下。

  • three (three.js)
  • jquery
  • webpack
  • @types/three (three.jsの型定義)
  • @types/jquery (jqueryの型定義)
  • ts-load (webpackでTypeScriptコンパイル用)
  • typescript
  • http-server (簡易HTTPサーバー起動)

手順にするとこんな感じ。

npm init
npm install --save jquery
npm install --save three
npm install --save-dev http-server
npm install --save-dev webpack
npm install --save-dev ts-loader
npm install --save-dev typescript
npm install --save-dev type@jquery
npm install --save-dev type@three

最終的なpackage.jsonはこんな感じ。

{
  "name": "threejs",
  "version": "1.0.0",
  "description": "",
  "main": "index.html",
  "scripts": {
    "build": "webpack",
    "test": "http-server"
  },
  "author": "tyabuta",
  "license": "ISC",
  "dependencies": {
    "jquery": "^3.2.1",
    "three": "^0.84.0"
  },
  "devDependencies": {
    "@types/jquery": "^2.0.41",
    "@types/three": "^0.84.3",
    "http-server": "^0.9.0",
    "ts-loader": "^2.0.3",
    "typescript": "^2.2.1",
    "webpack": "^2.3.2"
  }
}

index.html

index.html には、webpackにより出力されるバンドルファイルをscriptタグを使って読み込むようにするだけです。

<html>
    <head>
        <script src="assets/bundle.js"></script>
    </head>

    <body>HELLO</body>
</html>

webpack の設定

webpackを使うには、webpack.config.js というファイルを用意しておくとwebpackコマンド叩くだけで、ルールに従って1つのバンドルファイルにしてくれます。

module.exports = {
    entry: "./app.ts",

    output: {
        filename: "./assets/bundle.js"
    },

    devtool: "source-map",

    resolve: {
        extensions: [".ts", ".js"]
    },

    module: {
        rules: [
            { test: /\.ts$/, loader: 'ts-loader', options: { transpileOnly: true } }
        ]
    }
};

出力されたバンドルファイルをhtml側で、
scriptタグで読み込むだけです。

entryに設定したファイルから、requireで取得したファイルが全て芋づる式に取得され、1つのバンドルファイルに変換されます。

エントリー用のファイル作成

エントリーに設定するファイルは、
app.ts とします。
TypeScriptで記述するけど、もちろんJavaScriptでもいいよ。

require によって指定したファイルは、webpackによって、最終的にバンドルファイルにまとめて出力されます。

内容は、前回のThree.js のデモをTypeScript用に書き換えたやつです。

import $ = require("jquery")
import THREE = require("three");

$(function () {
    let $mainFrame = $("body");

    // シーン、カメラ、レンダラを生成
    let scene = new THREE.Scene();
    let camera = new THREE.PerspectiveCamera(75, $mainFrame.width() / $mainFrame.height(), 0.1, 1000);
    let renderer = new THREE.WebGLRenderer();
    renderer.setSize($mainFrame.width(), $mainFrame.height());
    camera.position.z = 5;
    camera.position.y = 1;

    // 自動生成されたcanvas要素をdivへ追加する。
    $mainFrame.append(renderer.domElement);

    // ここらへんは好きなオブジェクトをシーンに突っ込んじゃってください。
    let geometry = new THREE.BoxGeometry(1, 1, 1);
    // let material = new THREE.MeshBasicMaterial({color: 0x00ff00});
    let material = new THREE.MeshNormalMaterial();

    // Asixヘルパー
    let axisHelper = new THREE.AxisHelper(10);
    scene.add(axisHelper);

    // Gridヘルパー
    let gridHelper = new THREE.GridHelper(20, 5);
    scene.add(gridHelper);

    let cube = new THREE.Mesh(geometry, material);
    scene.add(cube);

    // コールバック関数 render をrequestAnimationFrameに渡して、
    // 繰り返し呼び出してもらう。
    let render = function () {
        window.requestAnimationFrame(render);
        cube.rotation.x += 0.01;
        cube.rotation.y += 0.01;
        renderer.render(scene, camera);
    };
    render();

    $(window).keypress(function (eventObject) {
        if ('h' == eventObject.key){
            camera.rotation.y += 0.01;
        }
        if ('l' == eventObject.key){
            camera.rotation.y -= 0.01;
        }
        if ('j' == eventObject.key){
            camera.rotation.x -= 0.01;
        }
        if ('k' == eventObject.key){
            camera.rotation.x += 0.01;
        }
    });
});

tsconfig.json の設定

TypeScriptのコンパイル用に、tsconfig.jsonというファイルを用意します。

特にコンパイルオプションとかまだわかってないので、下記のような空っぽのファイルでOK。

{
  "compilerOptions": {
  }
}

コンパイルする

これで準備はできました。

npm run build
で、webpackコマンドが動きます。

コンパイルに成功したら、assets/bundle.js というバンドルファイルが出力されます。

実行してみる。

index.html を直接ダブルクリックしてもいいが、
簡易httpサーバーを立ち上げてみてみると尚よろしいです。

npm run test

おしまい

jQuery や、Three.js はCDNの形で
バンドルする事も可能みたい。

また、簡易HTTPサーバーにhttp-serverをインストールしているが、webpack-dev-sever というのをつかえば、watch しながらhttpをリロードする事も出来るらしい。
(まだ試してない…)

次も頑張って更新します〜。

コメントを残す