ようやくthree.jsのインストール方法が完璧にわかった話:importmapを理解せよ

2022年2月27日

テクノロジー

eyecatch 密かにVR・ARにトライしようとしている、ユゲタです。 three.js、いや〜よくできたWebGLライブラリですね。 何から何までサポートされていて、痒いところに手が届くって、まさにこういうツールなのだと実感しました。 でも、環境設定をするのに、バージョン差異があったり、任意ブラウザでしか動作しないという、初心者には厳しい一面もあって、なかなか受け入れるのに時間がかかるライブラリでもあるかもしれません。

バージョンアップはいきなりやってくる

まず、three.jsの大きなバージョンアップは、@0.127までのバージョンと、@0.128以降のバージョンで大きく変わっています。 そのままバージョンアップをしてしまうと、モジュール読み込みの際にエラーが出てしまうでしょう。 どのようなバージョンアップがあったのかというと、three.jsは、色々な機能をそれぞれ、ページ内で使う機能だけをimportして使うというエコシステムになっているのですが、 この読み込み方法で、主要なモジュール(何故か全部ではないので要注意です)が内包する共通モジュールの読み込み(three.module.jsファイルの事)が、それまで相対パスで書かれていたのに、"three"とだけなっています。 それにより、読み込み時にimport関数は、"/" , "./" , "../"のいずれかで始まる記述でないとエラーになるという仕様に引っかかって立ち上がらなくなってしまいます。 では、これはどうすればいいかというと、以下の様に呼び出すHTMLに記述をします。 { "imports": { "three": "/node_modules/three/build/three.module.js" //※インストールしたthree.jsのパスを記述 } } </script> importmapという新しい設定方法で、three.jsは、いち早くこの方式を取り入れたんですね。 でも、残念なことに、この記述でちゃんと動作するのは、Chromeブラウザのみ。 Safariブラウザも、Firefoxブラウザも、2022年2月現在には、未搭載機能です・・・orz そこで登場したのが、"es-module-shims.js"というライブラリ。 これは、機能未搭載のブラウザにその機能を提供してくれる、一時凌ぎライブラリです。 こういうライブラリ地獄に陥る要因はなるべくなら使いたくないんですが、three.jsの方向性を考えると、使わざるを得ません。 CSNを利用して簡単に書くと次の様にするだけで、SafariでもFirefoxでも動作するようになります。 ※npmでmoduleインストールすることもできるので、公開サーバーにはそちらを利用ください。 <script async src="https://ga.jspm.io/npm:es-module-shims@1.4.6/dist/es-module-shims.js"></script> <script type="importmap-shim"> { "imports": { "three": "/node_modules/three/build/three.module.js" //※インストールしたthree.jsのパスを記述 } } </script> SafariとFirefoxのバージョンアップを見守って、これらのモジュールが外せる日を待ちたいと思います。

imnportするモジュールについての説明

上記のimportmapの記述をしたら、下位バージョンでの記述で動作はするのですが、できれば、importmapバージョンの記述にも対応しましょう。 threejsは、html部分にscriptタグでthree.jsをそのまま読み込んでも使えますが、ここでは、three.jsモジュールの読み込みを自分の作ったjavascriptファイル内だけで行う方法を説明したいと思います。 よく使うGLTFLoaderと、OrbitControlsモジュールを読み込むパターンを参考値として紹介します。 import * as THREE from 'three'; import { GLTFLoader } from '/node_modules/three/examples/jsm/loaders/GLTFLoader.js'; import { OrbitControls } from '/node_modules/three/examples/jsm/controls/OrbitControls.js'; 1行目はこれまで、 import * as THREE from '/node_modules/three/build/three.module.js'; と書いていたのを、"three"とimportmapで設定したパスに自動で置き換えてくれるので、簡単に記述できるようになったんですね。 なんでthreejsはこんなことをやったのかというと、ライブラリ内にはたくさんのモジュールが入り組んで搭載されていて、それらを互いに参照する際の相対パスを書いてあるのが少し汚いソースに見えてしまうのを防ぎたかったのではないでしょうか? これはあくまでユゲタの想像なので、本当の開発理由は分かりかねますが、とにかく、こうした技術対応を今後もしていく覚悟ができた、importmapについての理解でした。

このブログを検索

ごあいさつ

このWebサイトは、独自思考で我が道を行くユゲタの少し尖った思考のTechブログです。 毎日興味がどんどん切り替わるので、テーマはマルチになっています。 もしかしたらアイデアに困っている人の助けになるかもしれません。