I get TypeError: Module specifier, 'three-nodes/core/NodeFrame.js' does not start with "/", "./", or "../"
.
The following (from your examples) is not suppored by Safari:
<script type="importmap">
{
"imports": {
"three": "./jsm/three.module.js",
"three-nodes/": "./jsm/nodes/"
}
}
</script>
How can this be fixed?
I think Github repo needs a fix since importmap
is not a standard and only Edge and Chrome support it so far: "importmap" | Can I use... Support tables for HTML5, CSS3, etc
I included <script async src="https://ga.jspm.io/npm:es-module-shims@1.5.17/dist/es-module-shims.js"></script>
but it still doesnât work.
My app just doesnât launch in Safari and Firefox but it works in Edge and Chrome.
I just realized that none of these official demos work in Safari or Firefox.
Example:
https://threejs.org/examples/?q=nodes#webgl_nodes_materials_physical_clearcoat
This shows a black page for me in Firefox:
This is not really a bug, more like a difference between browser implementations. The CanIUse site you linked to also gives the solution to make the Three.js examples you referred to work in Firefox: you simply need to set the dom.importMaps.enabled
flag in about:config
.
So, just open a new tab in Firefox, type about:config
in the address bar, look for importMaps
and double click it to set it to true
. Refresh the Three.js examples link and it will work - it does for me as well, after setting up Firefox like this.
P.S. I donât know about Safari, never used it, never owned or will own a Mac, and so on. Maybe someone else could cover this part, if a solution exists in this case, that is.
1 Like
One more thing, regarding not having about:config
on iPhone: if it can be done on Firefox for the iPhone (it certainly can be done on Android), maybe you can request âthe desktop version of the pageâ from the browserâs menu (this is how itâs called, as far as I remember), and there you might be able to have more configuration options, except that the page wonât automatically fit your phone and such since it will run as if on a desktop device.
This doesnât quite solve the issue, but just in case it helpsâŚ
The import map âshimâ included on these examples is supposed to make it work in browsers that donât support import maps⌠I think there may indeed be a bug, or some other limitation here, it seems to just be affecting the examples using the material nodes system.
In any of my own projects I would use some sort of bundler like Vite, to compile all the imports into a bundle and deploy them together, in that case the browser support for import maps doesnât matter, I donât need a shim, and things typically load more quickly.
Thanks for your help.
iPhone has âexperimental featuresâ list in âSettingsâ but âimport mapsâ doesnât exist at all so it canât be enabled even then.
iOS/Safari = doesnât work (canât be enabled)
iOS/Chrome = doesnât work (canât be enabled)
Mac/Safari = doesnât work (canât be enabled)
Windows/Firefox = doesnât work (can be enabled)
Android/Chrome = works
Windows/Chrome = works
Windows/Edge = works
1 Like
In any of my own projects I would use some sort of bundler like Vite, to compile all the imports into a bundle
Iâm currently exploring webpack to generate bundle.js but I also use live reload on every file change and I want to use the Console to debug JavaScript (I need separate files) so such workflow with compiling bundle.js via Node.js is⌠not very good And itâs a lot of complicated additional setup and management
I would have to have bundle.js for iPhone and separate files for Windows/Chrome development.
(Also, webpack actually takes like 5-10 seconds to compile bundle.js so Iâd lose automatic live reload on both iPhone and Windows/Chrome.)
Some related topics here, here, here (yeah, I know, not that trustworthy, but anyway), or here, in case an answer can be found buried there.
It seems running Three.js on iPhone is a case of some things work, some donât. Unfortunately I couldnât find much about the specific iPhone and import maps topic.
Thanks, so far everything was working fine for me on iPhone until I added âimportmapâ in <head>
which makes the app not open.
The preferred solution would be to remove importmap
from github repo and reference everything by relative paths.
That would fix many problems for many people.
Yep, indeed - not sure the devs will share that opinion though. For the record, Three.js itself does work without import maps (last time I checked) if using the Three.js
file instead of Three.module.js
one and adding it as a separate <script>
in the HTML (hopefully I remember correctly that part, since I donât currently use it anymore). I guess itâs the other additions to Three.js (like the controls, for example) that require ES6 module syntax, and by extension, import maps.
I tried to avoid import maps myself when starting with Three.js but gave up on it. Some of the âsolutionsâ I was reading at the time mentioned rewriting stuff to use require
instead of import
, or in any case, something similar. It was too much trouble for me to even think about such methods, so between the N workarounds involving CORS and the workarounds related to ES6 module syntax and import maps, here I am. All these little things make it harder for the user / developer, and as a result also prevent a wider adoption of the library (the other being the techincal math involved).
Unfortunately, this causes larger issues with dependencies, build tools, and bundlers.
I strongly encourage using build tooling like Vite.js, for any JavaScript work involving dependencies. Doing so will avoid any need for import maps or modifications to these imports.
For those prefer not to use build tools, you will either need to use an import map, or to modify imports from âthreeâ to relative imports in the files you are depending on.
I would emphasize that import maps do appear to work with all examples except those using material nodes, so there is almost certainly a bug you could report to three.js about those specific examples, and this could likely be fixed. The browser itself does not need to support import maps, the import âshimâ handles that.
1 Like
A little question, if I may, since I didnât work with âbundlesâ, âshimsâ and all these ânewâ ways of making things that used to work fine right off the bat 5 or 10 years ago work again: isnât bundling or shimming (sorry, not an expert in such semantics) a problem when debugging? I mean, as far as I know, these tools basically âpackâ all your JS files / modules / dependencies into a single file / source that can be then used instead of the former multiple file system. While it may be suited for the final version of those JS dependencies, what happens if you still need to modify or develop those dependencies and use the packed result at the same time? Is the bundling / packing instantaneous and happening every time you run your main module in a page or itâs something similar to packing files in a .zip in that it takes time and the result is unintelligible to be edited, developed further, etc? Also, does it need an active internet connection, if by any chance that packing is done on a server, or it can be performed locally / offline?
Sorry for the side question, but Iâm just curious. I would have reported the assumed bug myself on GitHub if I had an iPhone or a Mac along with Firefox / Safari in order to replicate the issue, unfortunately I donât, so itâs up to the OP or someone else running on similar systems.
âbundlesâ, âshimsâ and all these ânewâ ways of making things that used to work fine right off the bat 5 or 10 years ago work again: isnât bundling or shimming (sorry, not an expert in such semantics) a problem when debugging?
So funny.
Continuation:
I generated bundle.js using Webpack but I didnât manage to make it work because import { TextGeometry } from './bundle.js'
returns that bundle.js doesnât have such export. So far I gave up after like 6 hours of trying to make it work. And besides all my scripts would have to import
from bundle.js so I donât want that because Iâd have to change all import
references to bundle.js in all my scripts.
I found that dynamic import()
was what was crashing my app so I believe itâll be working without bundle.js and with âES Module Shimâ polyfill.
Also, it turns out that Mac/Safari console doesnât actually show all errors related to this and I had to click âAllâ tab to be able to debug this (took me like 1 hour to figure this out, Chrome and Edge show all errors in the Console by default).
Shims (also called âpolyfillsâ) are not really related to build tools or bundlers. Shims just scripts that âpatchâ in missing features in old browsers. JavaScript developers have used shims for more than a decade, e.g. to patch missing or broken features in Internet Explorer. If you need a feature like import maps, and your browser doesnât have it, a shim can add that feature to older browsers. Personally I do not use the import map shim, because I do not use import maps. Using a build tool like Vite (or Webpack or Parcel or Browserify), it packages everything into a single file, and thereâs no need for import maps, or even imports in most cases.
Modern build tools like Vite include solutions for the things youâre describing here. Details inline â
isnât bundling âŚa problem when debugging
All browsers support sourcemaps, allowing you to view and debug the source files in the browser, even if the files were technically packed into a single file. This does not typically affect debugging.
Is the bundling / packing instantaneous and happening every time you run your main module in a pageâŚ
It is practically instantaneous in most projects, although I have worked on a few that were slow (looking at you, Closure Compiler). Newer tools like Vite include Hot Module Replacement (HMR) so you donât even need to reload the page to see your changes, the updated code is just swapped in on the fly. But even without HMR, updates are very fast.
Also, does it need an active internet connectionâŚ
Local, no need for an internet connection once the build tool has been installed.
2 Likes
If you have lots of scripts on the page importing from the bundle, then youâre doing something very different from typical Webpack usage. Typically there is only one script on the page in the end, the bundle, and the bundle does not need to be imported into anything, it just runs. I suppose there are reasons you might do this differently though.
If you prefer to manage dependencies and files separately and not bundle them, thatâs fine, but personally I find this makes things much harder. Most JavaScript projects relying on dependencies use some kind of bundler. Webpack is one of the more complex ones, others are simpler.
Oh, well, Iâm familiar with polyfills, but I had no idea shims were just that. Thanks for taking the time to point out the details that I mentioned and how they are handled by these tools / methods, that makes it all clear for me.
I wonât switch from using import maps for now, since my current project involves running the Three.js related code in a desktop application (Rainmeter, though I built it so it can run more or less the same in the browser as well without any problems), and Iâd like to avoid increasing its own list of dependencies (e.g. the desktop application, the plugin that allows it to run webpages, Edgeâs WebView2 as a platform for that, Node.js to run it through a local server and debug it) to zillions of stuff for every little thing along that process - but this is certainly useful to know, for the future.
What youâre using seems like less trouble than I thought, so I guess there positives exist as well - itâs just that things used to be way simpler than this in the past and itâs a pitty they âevolvedâ into this labyrinth of âyou need this to do thatâ, thatâs all.
1 Like
Yeah, I do agree that JS ecosystem tools have gotten more complicated over the past decade, and the learning curve is steeper than it should be. But I find the pain involved in trying avoid those tools (given where the ecosystem is, and is headed) is even worse at this point. Up front costs aside, these tools do (IMHO) work well once theyâre set up.
1 Like