Reaching threejs_api module from init file

I am trying to install the latest version of threejs, and I am going by the directions here:
https://threejs.org/docs/index.html#manual/en/introduction/Installation

I am going according to " Install from CDN or static hosting". And I am having my own server.

Here is the code.

<script async src="./shims_file.js"></script>
<script type="importmap">
  {
    "imports": {
      "three": "./three.module.js"
    }
  }
</script>
<script type="module">
  import * as THREE from 'three';
  const scene = new THREE.Scene();
</script>

I can have this given code run.

Now the first thing I want to do, is to put the threejs code into a script of it’s own.
I have a module, that serves as an API which let’s me talk to threejs.

So instead of the last script, the module script. I have:

<script src="./threejs_api.js"></script>

It runs without error, regardless of if I hadd type=“module” or not.

Now that I have defined the threejs api module.

I need to make an instance of it.
So I have another script tag,

<script src="init_threejs.js"></script>

Which tries to make an instance of the threejs_api module.
I then get error:

mthreejs_api is not defined.

It is like it cannot reach the variable from the previous script tag.

In the previous script tag, the threejs api. It is not clear to me, where I should put the

import * as THREE from 'three';`

If I do add it in the first line of the constructor, I get error:

Uncaught SyntaxError: import declarations may only appear at top level of a module

But I can put it in the top line of the entire threejs_api file. So I put it there.

But the initiation file still cannot reach the threejs_api module.
So it can’t see it so I can’t make an instance of it there.

How do I reach the threejs_api module, from the init file?

you will not get a working set up with that easily.

the docs have already been remade and will hopefully be merged soon, you can use them from this link: three.js docs

TLDR, browser esm is not a standard but an incomplete spec that will need years to be stable.

That doesn’t really answer the question.

Is it not possible to access threejs, from a different script file?

The new installation documentation is exactly the same in this regard.

I am not trying to be like everybody else. I am trying to move the correct way forward.
It is crucial to have an api for how I speak to those modules.
Otherwise the system is bound to get garbled up in complexity.

accessing a module from another module is the point of modules. but you need an environment that supports it. instead of tags, shims, maps all you need to do is npm install three and import * as THREE from 'three' in your index.js. every module that has exports can be imported from elsewhere and everywhere.

But according to the directions, it should be possible to use Threejs just via “import from cdn”.

I am trying to avoid using npm. Is that not possible?

What does it mean for a module to “have exports”?

You only need one module script tag on the dom, lets say you use init_threejs.js for that, now inside your threejs_api.js file you can use export declarations…

function threeAPI() {
//do stuff
} 
export {threeAPI} 

Now from inside your init_threejs.js module you can simply import the functions, classes, variables however you chose to construct your setup…

Import {threeAPI} from './threejs_api.js' 

Hope this helps and makes module exports a little clearer

1 Like

I think you ment

import {threeAPI} from './threejs_api.js' 

But yes, this is definitely helpful. Thanks.

correct updated the typo, but you get the idea :slight_smile:

In the import. I have to use type=“module”, for this to work.

But my dream is to get out of this type=“module”.

If I have type=“module”.
Only then can I access the variable via import.

But in type=“module”, I cannot define global variables anymore for instance.
Which I would then access in future script tags.

How can I break out of this loop.
How can I get a type=“module” variables, into the free world?

type=“module” is the more reliable and secure way to use js over older es5 applications, anyway, if you want to load other files that are in es5 it’s good to know that any script with the tag type=“module” is similar to the older deffered tag (fwiu) in that modules will typically wait till the rest of the dom above is loaded and ready, this means if you wanted to use a non es6 module, lets say jquery for instance, putting the jquery script above the module script on the dom…

<script src="jquery.js"></script>
// not sure what's inside your threejs_api.js 
// but it would go above the module to be recognised as defined
<script src="./threejs_api.js"></script>
<script type="module" src="init_threejs.js"></script>

will allow access to jquery from the module, however, if both scripts require imports such as three they will need to be used with the es6 module workflow as above when using the latest versions of the library

the answer is yes, see this little demo, the question is why would you want to do that?

1 Like

Yes it worked in my code when i did window.var=var; And then I could access it within onload.

I have created an entire universe, where I am solving all sorts of problems. And Threejs is just one external module. If I couldn’t get a variable out of type=“module”. My entire computer system would be basically gone. My system completely depends on multiple script tags in a row, not with type=“module”. Where some global variable glues everything together.

In that url they say to not use window.x=x; in production, but don’t bother telling why.
I also see no other solution available at all.

So it doesn’t seem like I have a choice.

it sounds like you could do with refactoring your setup. You can dispatch a CustomEvent with the detail set to the variable value but you’re shooting yourself in the foot for the long run, if it’s an app you’re planning to scale id take @drcmda’s suggestion from above…

Refactoring is my middle name.

I just barely managed to go back to previous version.

Will try tmrw another time to upgrade to latest version.

I don’t understand, how or why the other version is better.

And I can’t but see that my current way of doing things, is far better.

I can so be wrong though.

Here is my current system,
buttons are wasdeq, 1,2 and z for mouse.
https://openage.org/it/3d/index.html

and tmrw… another day of trying to upgrade to new version.