I should probably start with the fact that I use Three.js in an unusual way
The lib code is inside the script element, without any src attributes, directly.
Don’t ask why, it just has to work this way for this case
So the question is how to use the modules? What workarounds can we apply? Thanks for any information
Well, if you do one import in some custom unusual way - be prepared that you’ll need to do the rest in the same, unusual way. So if you inline three module, why not just inline other necessary submodules as well?
You may also try using import maps, but hard to say if it’d work with your custom solutions.
I’ve tried this, adding ‘FirstPersonControls.js’ as an inline-script
The problem is that from the very beginning the code inside already requires ‘three’ as a module
import {
MathUtils,
Spherical,
Vector3
} from 'three';
Apart from removing the import statement, you also have to remove the export statement as well as to fix all imported names, if needed. For example, in my case I had to rename all usages of Vector3 into THREE.Vector3, all Mesh into THREE.Mesh and so on. But as @mjurczyk, you would have to spend some time manually editing the source code.
Oh, if you import a module that imports other modules, you have to do this recursively for all modules.
Maybe it would be easier to pick a non-moduled version of Three.js and its libraries (e.g. r147). Then you can manually merge all files into one script.
PS. The title of the thread does not correspond to the question in the post.
assuming you have <script>your code here</script> situation - yes, you could create the type=module script element, put the code there and append it to document.head or .body
const s = document.createElement('script');
s.type = 'module';
s.textContent = 'import { REVISION } from \'https://threejs.org/build/three.module.js\'; console.log(REVISION);';
document.head.appendChild(s);
So far, no errors, and the most interesting thing: I only needed FirstPersonControls.js, which needed 3 other modules, and another one needed another one, you also need to hit the sequence - otherwise it won’t work.
it won’t work. modules and IIFE (immediately invoked function expressions) don’t mix. you either use one or the other. it would take you days to manually edit and hack modules back into IIFE and it’s not enough to remove imports/exports, you’d have to prefix every threejs construct with THREE. and make sure they get loaded in specific order, which — considering cyclic dependencies will be a nice puzzle.
IIFE has been abolished a decade ago, threejs has stopped supporting it. it was an anti pattern if there ever was one — why you want to mess that is beyond me, but just use a threejs from a year back and you’ll be OK.
149 is a module, i’d say chances are slim to none you’d get this converted into IIFE again. it’s kind of awfully specific, why 149, why does it need to work like in the earliest days of computing. i know we’re not supposed to question anything here but did they tell you at the job?
it seems like it converts just fine, 3js devs just do not want to do it any more. so far the only complaint I saw was about top-level “await” somewhere in webgpu code
I made an example using COW language before here you can check the source code the entire code (including all the three dependencies) is reduced to uppercase / lowercase character variations of the word “Moo”… at the end of all that i just used
this will allow you to dynamically import modules without having to use any iife stuff, if i remember rightly the only caveat was that three imports had to be absolute URL paths such as CDN links…
PS: you can decode the COW string in the source code here if you paste the COW sting in the second box…
i just realised the question is not really related to the title… did you…
as @mjurczyk suggested? this would surely work for your use case and be a lot easier than converting modules, three has been written in a pretty clever and efficient way…