-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix some problems related to module #22
Conversation
Ver.1.1.1 : Fix tooltip, Revision of texts
Fix three.module.js path
original source (tag: r142) - [OrbitControls.js](https://github.com/mrdoob/three.js/blob/r142/examples/jsm/controls/OrbitControls.js) - [PointerLockControls.js](https://github.com/mrdoob/three.js/blob/r142/examples/jsm/controls/PointerLockControls.js)
to fix `Uncaught TypeError: Failed to resolve module specifier "three". Relative references must start with either "/", "./", or "../".`
importmap reference: https://github.com/WICG/import-maps importmap does not work in Firefox
このコミットをFirefoxで見たときのスクショ 1行目はよく分かりません(消せない)。2行目がブラウザネイティブのモジュール解決機構が失敗している様子。3行目は関係ないです。4行目までにpolyfillがモジュールを解決して2行目のエラーは無視してOKである旨を4行目に表示しています。 比較のためにpolyfill無しの1つ前のコミット(6fb8d0b)をFirefoxで見た様子とChromeで見た様子を載せておきます。なおChromeはネイティブでimportmapをサポートしているのでpolyfillしてもしなくても変わりません。 Firefox(読み込み中の画面で止まる) 警告を消す方法 利用しているpolyfillのes-module-shimsには2つのモードがあります。今はpolyfillモードですが、shimモードにするとネイティブのモジュール解決機構が走らなくなるので2行目のエラーは消えます。ただしshimモードにすると今度は(js/main.jsから監視できるタイミングでは)DOMContentLoadedイベントが発火しなくなるという問題があります。この場合はjs/main.jsでDOMContentLoadedイベントにリスナを登録する前にreadyStateをチェックするなど工夫が必要です。 もしくは現状でもjs/*Loader.jsで行われていますが ef35db4 でコピーしてきたjs/*Controls.jsに以下のようなカスタマイズをすればpolyfillなしでも動きます。あと1行目のasm.jsのエラーも消えます。 // (変更前)
import {
EventDispatcher,
...
} from 'three';
// (変更後)
import {
EventDispatcher,
...
} from '../build/three.module.js'; |
es-module-shimsをpolyfillモードで使用したとき、js/main.jsで登録したDOMContentLoadedイベントで呼ばれるはずのコールバック(app.init())が呼ばれていませんでした。vhc.html側でwindowとdocumentそれぞれにイベントリスナをつけて調べてみました。以下に実行結果を示します。 そもそもDOMContentLoadedイベントはdocumentで発生するイベントであり、以下のコードは親に向けて伝播してきた(バブリングしてきた)イベントを見つけてコールバックを呼びます。第三引数の window.addEventListener('DOMContentLoaded', doSomething); 上のスクショを見れば分かるように、DOMContentLoadedイベントの発火にともなって呼ばれたコールバック(最初の2つ)はどちらもバブリングフェーズで呼ばれています(document→windowの順であることからも分かる)。しかしこの時点ではpolyfillによるモジュール解決が完了していない(緑文字のメッセージがまだ出ていない)のでjs/main.jsでコールバックを登録できていない状態です。その後モジュールが解決され、上に示した polyfillによる実際のコードはこの辺です。 https://github.com/guybedford/es-module-shims/blob/main/src/es-module-shims.js#L490,#L493 document.dispatchEvent(new Event('DOMContentLoaded')); ただしEventコンストラクタにイベントの名前だけ渡して第二引数のオプションを何も渡さなかった場合、生成されたイベントはバブルしません(MDN)。つまり子要素から親要素に向かって伝播しません。したがって先ほどバブリングフェーズで呼ばれるように登録したコールバックはいつまで経っても呼ばれません。 これを解決するにはキャプチャリングフェーズ(親要素から子要素の方向に順にコールバックを呼んでいく段階)でコールバックを呼ぶようにリスナを登録するか、windowではなくdocumentに直接リスナをつけるかする必要があります。 またはこのような方法もあります。 function doSomething() {
console.info('DOM loaded');
}
if (document.readyState === 'loading') { // Loading hasn't finished yet
document.addEventListener('DOMContentLoaded', doSomething);
} else { // `DOMContentLoaded` has already fired
doSomething();
} |
このコミットより前のコミットがapproveされなかったとしてもこのコミットは残していいと思います。なぜならDOMContentLoadedイベントを発火させているのはブラウザか今回の場合はpolyfill用のes-modules-shimであり、どちらもdocument.DOMContentLoadedイベントでありdocumentにリスナをつけるのが妥当だからです。 |
変更点
THREE.OrbitControls
をOrbitControls
で置換THREE.PointerLockControls
をPointerLockControls
で置換<script src="js/three.min.js"></script>
を削除(リポジトリからもまだ削除していません)OrbitControls
の仕様変更に伴うエラーを修正 Examples: Make domElement to a mandatory parameter for all controls. mrdoob/three.js#17612 を参照してくださいコピーしてきた2つのファイルを含むThree.jsのバージョンは現時点の最新リリース
[r142](https://github.com/mrdoob/three.js/tree/r142)
です。もともとのjs/*Loader.jsやbuild/three.module.jsのバージョンが分からなかったので最新リリースを持ってきました。なのでバージョンの不整合が起きています。今の所エラーは無いですが、これを期にすべてアップデートするのも吉だと思います。importmapについて
importmapを使用しているのはThree.jsのソースからコピーしてきている「Three.jsのコアには含まれない機能のためのJavaScriptファイル」を無修正で使いたいからです。ここでいう「Three.jsのコア」は
build/three.module.js
のことであり、「含まれない機能」はLoaderやControlers等Three.jsのexamplesディレクトリに含まれるようなファイルのことです。ドキュメントにも以下のように表現されています。こうしたファイルを今まではコピーしてきた後で
import {} from 'three'
の部分をimport {} from '../build/three.module.js'
へ手作業で書き換えていたのだと思います。どうやっていたのか私は知らないのでここは想像になります。こうしないとブラウザがthree.module.jsを解決できないことは周知の事実だと思います。書き換える作業はなんのことはないといえばなんのことはない作業ですが、書き換えたことによるバグを減らすには書き換えなければいいので、依存は増えますが、あえてimpormapを使うことを提案します(こういうことはIssueで書くべきですね、、、)。もちろんメリットだけではないので意見をいただければと思います。
動作確認に用いた環境
Arch Linux (x86_64), Firefox 102.0, Google Chrome 103.0.5060.53(Official Build)
close #21