0

I am trying to import the threejs and GLTFLoader modules, both of which ( for testing ) are in the same root/js/ folder..

import * as THREE from './js/build/three.module.js'; // Works fine 
import { GLTFLoader } from './js/build/GLTFLoader.js'; // Throws a disallowed MIME TYPE error

I get the mimetype issue but the error isn't thrown when in the three master 'structure', so why doesn't this work?

EDIT:

So when uncommenting the import GLTF line, the error thrown is the following:

Loading module from “http://localhost/dev/project/build/three.module.js” 
was blocked because of a disallowed MIME type (“text/html”).

It seems to refer to the three.module.js path, however, when that line is commented out, it all loads fine with no errors. The paths are correct for all files/folders too.

Bilal
  • 3,191
  • 4
  • 21
  • 49
Toki
  • 517
  • 3
  • 9
  • 27
  • When working with modules always use `examples/jsm` files, those contain the modular version of the respective files. For more information, check [Import via modules](https://threejs.org/docs/#manual/en/introduction/Import-via-modules) – ScieCode May 10 '20 at 15:39
  • HI, that is the modular GLTFLoader from /jsm/ which I'm using. I am not using webpack or similar to 'bundle' them - could that be the issue? – Toki May 10 '20 at 15:45
  • Bundling shouldn't be the problem here, can you edit your post to include the exact error thrown? – ScieCode May 10 '20 at 15:59
  • The problem seems to be related with GLTFLoader internal import, not your three.module.js import. As you can see from the error url, it's missing "js" in it. Change the relative path right at the start of `GLTFLoader` so that it's able to correctly load three.js build and that should suffice. – ScieCode May 10 '20 at 16:23
  • Yeo - that's cracked it, cheers!! – Toki May 10 '20 at 16:36
  • Does this answer your question? [GLTFLoader.js:9 Uncaught SyntaxError: Cannot use import statement outside a module](https://stackoverflow.com/questions/61191061/gltfloader-js9-uncaught-syntaxerror-cannot-use-import-statement-outside-a-modu) – gman May 13 '20 at 15:01

2 Answers2

0

I realise my question was somewhat unclear but essentially what I was trying to do is use the modular three.js functionality whilst retaining the entire project in a single root folder - ie not having to traverse up to the 'build' files.

I feel like this is probably something that is often required (in the absence of webpack et al.) since a website would generally be contained within in a single root folder.

After some helpful input I was able to resolve this with the following..

The Folder Structure:

root/
 |
 | -- index.html
 |
 |
 | -- /build/
 |      |
 |      | -- three.module.js 
 |
 |
 | -- /js/
        |
        | -- app.js*
        |
        | -- /jsm/
               |
               | -- /libs/ ...        
               | -- /loaders/ ...

The Imports ( in app.js )

import * as THREE from '../build/three.module.js';
import { GLTFLoader } from './jsm/loaders/GLTFLoader.js';
import { TWEEN } from './jsm/libs/tween.module.min.js';
import Stats from './jsm/libs/stats.module.js';

Hope this is of use to anyone searching for the same solution, and thanks as always to the community for the valued assistance!

Toki
  • 517
  • 3
  • 9
  • 27
-1

this line

import { GLTFLoader } from './js/build/GLTFLoader.js';

should be

import { GLTFLoader } from './js/examples/jsm/loaders/GLTFLoader.js';

and you should structure your three.js files to match the official three.js folder structure.

See this answer

And I want to make it very clear, @ScieCode's suggestion of editing the GLTFLoader.js is not a good suggestion. If you follow that suggestion you're going to have to start editing all files you use from example/jsm like the OrbitControls.js file, the TrackballControls.js file, the EffectComposer.js file (and all the files it includes like MaskPass.js, CopyPass.js, Pass.js). And, if you ever grab a new version you'll have to re-edit all those files again.

Instead just use the official folder structure as pointed out in the linked answer and stuff will just work, no editing needed.

gman
  • 100,619
  • 31
  • 269
  • 393
  • I actually disagree with this answer. Yes, examples module files expect the same structure as they are served by three.js. But once you downloaded the file, you are no longer attached to this limitation. To change the file structure of your project, just to accommodate this, feels like the wrong approach. – ScieCode May 11 '20 at 05:00
  • Did you read the linked answer? The files have hard coded paths in them. Unless you manually edit all the files you must use the same structure or things will break. That's just what way ES6 modules work – gman May 11 '20 at 06:03
  • Yes, I did. And that's exactly what I'm talking about. Example files in three.js are meant to be used as a reference, not as literal and immutable files like the ones inside core. I think the correct way to approach this problem IS to actually manually adjust the paths to what fits your project and file structure, not to adjust your file structure to fit the files. – ScieCode May 11 '20 at 06:37
  • I wasn't saying that your answer is wrong, or that it doesn't work. I was just saying that I, personally, don't think it's the best approach. – ScieCode May 11 '20 at 06:41
  • So you're saying every time you download a new version of three.js you should manually edit each and every three.js source file to change it's internal paths to something else? You can not just copy the files anywhere you want because there are paths referenced inside those files. So it's not as simple a just choosing some random folder structure you like better. That won't work without manually editing up to 322 three.js source files. Just checking you understand what you're suggesting. – gman May 11 '20 at 06:58
  • Alright sir, calm down. Read what I said and just accept for what it is. I never said anything about editing source files. I explicitly said that example files are not the same as core files, that shouldn't be mutated. I've made it clear from the beginning that I was talking about example files. I'm very aware of what I'm suggesting. I'm not sure what is the big deal with that, the fact that I provided a different perspective or just that I disagree with you. – ScieCode May 11 '20 at 07:07
  • If you are working on a project that imports all example files, sure go for your approach. However, how many projects need to import more than 20 example files? I stand by what I said, your answer is not the best one for the vast majority of use cases. If you are upgrading three.js to a newer release, you already need to redownload all of these files, because they are version dependent, you'll already gonna need to fix many API changes. What is the big deal about manually updating the relative path of module imports? – ScieCode May 11 '20 at 07:14
  • I have nothing but respect for the work and effort you put into pushing WebGL forward, but you gotta accept that people disagreeing with you does not make them wrong or incapable of reasoning. This all could've been ignored if you just accepted what I said as a valid option to your answer, and the users can decide for themselves which path they prefer. – ScieCode May 11 '20 at 07:22
  • I still want to make sure I understand your suggestion because it would be different than everything else on this site. You are suggesting (1) download three.js and GLTFLoader.js and put them where ever you want (2) open GLTFLoader.js in your text editor and edit the code to point to where you moved three.js relative to where you put GLTFLoader.js. Repeat that process for any other files you download from three/examples/jsm. If you download a new version of threejs. Repeat the the process manually editing each file you downloaded. Is that what you're suggesting? – gman May 11 '20 at 07:45
  • The reason I'm asking you about this is your solution is it **requires editing the three.js source**. Not your own source, the three.js source code itself. If that's what you're suggesting fine. You can of course edit the three.js source code all you want. But most people choose not to edit the three.js source and use it as is. In order to use it as is you have to use the same folder structure because inside the three.js source are hard coded paths. Please acknowledge you're aware that your suggesting editing the three.js source code. – gman May 11 '20 at 07:52
  • (1) I'm not suggesting for anyone downloads three.js or GLTFLoader, if it was me I would use a CDN version. However, the OP stated a project structure in which he does, which is also a valid option, in that scenario I prefer my suggestion. – ScieCode May 11 '20 at 07:57
  • It's not a valid option though. it will get errors. You seem to be fundamentally missing that. – gman May 11 '20 at 07:59
  • (2) If you consider module import path part of source code, fine. That's what I'm suggesting, it's the same thing as saying that you need to alter the – ScieCode May 11 '20 at 07:59
  • If it's not a valid option, how the OP did exactly that, it worked as he would expect and he walked out happy about having the project working just fine? Seriously, I really don't understand what's going on here. – ScieCode May 11 '20 at 08:01
  • Also, just reinforcing what I already said 2 times. I don't consider example files to be three.js source, GLTFLoader is not a core file. You could argue that people shouldn't change it's implementation and to that I agree 100%, but adjusting the module import to be coherent with your project structure, there's nothing wrong with that. – ScieCode May 11 '20 at 08:10
  • You're missing the point. [Here's an example](https://glitch.com/edit/#!/achieved-charm-pawpaw?path=index.html%3A6%3A17). I copied three.module.js to a subfolder called foo. I also copied examples/jsm/loaders/GLTFLoader.js to foo. Running it [gets errors](https://i.imgur.com/XfMitiw.png). [Here it is using the official folder structure](https://glitch.com/edit/#!/opposite-cord-petroleum?path=index.html%3A14%3A25). [No Errors](https://i.imgur.com/rbraPld.png) – gman May 11 '20 at 08:38
  • As for why it worked for him he got lucky because he named the folder "build" so when `GLTFLoader.js` tries to load `https://hisdomain/build/../../../build/three.module.js` the ../../.. cancelled out at the root of his server and "build" happened to be the correct subfolder. As soon as he tries some other example like EffectComposer it will utterly fail because it will reference more files. – gman May 11 '20 at 08:40
  • Ok, I think I finally understand what's the problem. We are talking about different things, I suggested that he edited GLTFLoader internal module reference to point directly to the three.js build he downloaded. Not to alter the reference point to GLTFLoader in the main module script. This is what I suggested [no errors, everyones happy](https://glitch.com/edit/#!/join/df0ed987-85da-4a8e-b5c2-f63fdab343c3) – ScieCode May 11 '20 at 08:47
  • That's not remotely the best solution for most people. Why make it more work? Why tell them to edit files that don't need to be edited? When they download a new version and forget to fix the paths they'll come back to S.O and ask why isn't it working and we'll have no idea how to help them not knowing they edited the file. Further, you're asking them to edit more files. If you include EffectComposer.js then you also need to edit MaskPass.js, CopyPass.js, MaskPass.js, and Pass.js. And it gets worse and worse. Just use the same folder structure and save yourself the trouble. – gman May 11 '20 at 08:54
  • Fair enough, that's your opinion. I still believe my suggestion to be better, but I'm fine if we disagree. As long as it's considered a valid option, as it is. Regarding your point, that is true, there are side-effects as there is with yours. No library should have the power to enforce a set structure and organization in your project, three.js also doesn't have that power. As long as people understand that and don't blindly follow what you are suggesting, I'm completely fine if people choose your approach over mine. – ScieCode May 11 '20 at 08:59
  • No, it has nothing to do with "being on top". I think your suggestion is actively harmful. I think you've lead the questioner to a bad solution and it's going to cause problems for them in the future. So I want to make it extremely clear they should not follow your bad advice. Sorry if you disagree but I can't sit by and let them be mislead into future errors. – gman May 11 '20 at 09:07
  • If they change code structure and it breaks, people will come to S.O and ask questions about why it broke. Rather than teaching them about why it works like this, you are telling them to do it this way because that's what you find best. How's this any different? I'm disappointed, I thought higher of you. I'm done with this discussion. – ScieCode May 11 '20 at 09:16
  • Whilst reluctant to wade into this heartfelt debate, I should clarify a couple minor points. I was actually mistaken as to ScieCode's solution and what worked was retaining the structure whilst managing to fit everything within the same root folder - something the three master doesn't do (which is understandable), yet I needed the project to be within a single root folder w/o repacking - I wouldn't want to stick it on a domain, and have to use a subfolder to hold the actual project. Also I didn't want to have to use 'examples' folder name. You've both been very helpful, it's much appreciated! – Toki May 12 '20 at 17:14