Edited at

TypeScriptとwebpackとthree.jsでexamplesを使う

More than 1 year has passed since last update.


背景

three.jsには、examplesと称して便利なクラスが用意されています。

例えば、OBJLoaderと呼ばれる.objファイルを読み込むことのできるクラスなどがあります。

https://threejs.org/docs/#examples/loaders/OBJLoader

なぜかわかりませんが、npmモジュールとしてthree.jsを取り込んだ場合、examplesの中のクラスは取り込まれないようです。

しかし、@types/threeには定義されている・・・。

なんとか使いたい・・・!

そこで、imports-loaderで解決しました。


imports-loaderとは

モジュールをimportするときに、同時に定義しておきたいパラメータをいい感じに定義してくれるやつです。

たとえば、以下のようなモジュールがあった時、globalにjQueryが定義されていないと死ぬでしょう。


caller.js

import $ from "jQuery";

import sample from "./sample";
sample(); // -> エラー!!!!


sample.js

module.exports = function() {

$("foo").trigger("click");
}

webpackの場合、いい感じにモジュールを隠蔽してくれるので、通常、上記のモジュールではjQueryにアクセスできません。

そこで、imports-loaderがいい感じに変換してくれます。


caller.js

// ここが重要!

import sample from "imports-loader?$=jQuery!./sample.js";
sample();

↑のような呼び出し方をしておくと、以下のようにjQueryを定義して使えるようにした上でexportしてくれます。

import [読み込みたい何か] from "imports-loader?[事前に定義しておきたい変数名]=[変数を定義するためのモジュール名など]![読み込みたいファイル].js"

たぶん、Bootstrapなど、jQueryを事前に定義しておく必要があるモジュールを読み込む時に威力を発揮するような気がします。


converted-sample.js

var $ = require("jQuery");

module.exports = function() {
$("foo").trigger("click");
}


three.jsで使う

OBJLoaderの実装を確認すると、以下のようになっていました。


OBJLoader.js

THREE.OBJLoader = function() {

....
...

つまり、すでにglobalにTHREEが定義されているものとして実装されています。

ならば、imports-loaderが使えそうです。


caller.js

// OBJLoader ".js"まで必要!

import "imports-loader?THREE=three!three/examples/js/loaders/OBJLoader.js";
import * as THREE from "three";

new THREE.OBJLoader();
// do something.


こんな感じで出力されていました。


bundle.js

...

/*** IMPORTS FROM imports-loader ***/
var THREE = __webpack_require__(0);

/**
* @author mrdoob / http://mrdoob.com/
*/

THREE.OBJLoader = ( function () {
...


以上です。よろしくおねがいいたします。