Upward compatability: Module Loader Issue

Background: The programming pattern/recommenation in "Ee: invalid module" error. The module tries to use observable's variable worked at one time.

However, it now results in “invalid module”.

See: Issue: Requiring threeJS modules / Mario Delgado / Observable for detailed debugging.

That file is not an AMD/UMD module that you can require with d3-require, but a ThreeJS plugin that expects window.THREE to be present. require() will always fail here.

You must ensure that THREE was loaded first, ideally by loading everything inside the same cell:

  const THREE = window.THREE = await require("three@0.99.0/build/three.min.js");
  await require("three@0.99.0/examples/js/loaders/GLTFLoader.js").catch(() => {});
  return THREE;

You can then access the loader via


Indeed, that is the pattern that was being used before the original notebook started to experience the upward comparability issues.

To illustrate this, Issue: Requiring threeJS modules / Mario Delgado / Observable has been updated with your recommended code (using constant THREE2 at the end of the notebook); demonstrating that GLTFLoader is still not instantiated.

Update: Issue is sporadic. Initially using recommendation did not load the module.

It does get instantiated though:

Don’t try to test with multiple THREE instances in the same notebook. You will run into race conditions. Create separate notebooks for your cases.

I recommend to test out code snippets in Demo / Observable / Observable. The upsides of this approach are that the URL is easy to type (just /demo), that you’ll have a (mostly) clean slate, and that you can quickly discard the notebook afterwards.

Hmmm…Doesn’t reproduce with simple code pattern. However, opening the following url in an incognito window (to clear data) will sporadically generate the invalid module error (scroll down to bottom of notebook where THREE is defined):

DataVisual (Data + Visual) Design Pattern for WebGL 3D Assets / Mario Delgado / Observable (observablehq.com)

Again, this worked when notebook was originally published.

You’re pulling in an additional THREE instance (0.104) via your dataVisual import. This is causing conflicts via the race condition that I mentioned above because some plugins register themselves onto the wrong THREE instance.

You could try to reference dataVisual in your THREE cell to ensure that the instance has been fully loaded before you load version 0.99.

I double-check code for the dataVisual class and don’t see any reference to THREE in that specific notebook.

I guess what you’re saying is that the import of the class also brings along the THREE module in the notebook where the class is hosted; not a behavior I would expect.

In any event, I reconciled the versions between the notebooks; making them all 0.104 and re-tested. It appears to be cleared up for now.

This snippet appears multiple times in your class:

    const raycaster = new THREE.Raycaster();
    const mouse = new THREE.Vector2();

You can open the minimap in the side pane to spot cell dependencies more easily:

1 Like

Ah! Missed that…should have done a ‘find’ rather than a visual search. That being the case, the ultimate solution would probably be using the import - with option to force the imported class to use the local instantiation of THREE.