Where is the "three" location?

Forgive me for this really foolish question.

Every project code starts off with

import 	* as THREE 		from 'three';

Where is this ‘three’ location in a typical development environment?



i suggest you copy the threejs file on a local folder and then load it from local like so import * as THREE from "./folder/anotherfolder/threejs.min.js" from the folder you keep the threejs file.

I suppose I could do that.
I have a fully working environment that I setup quite a while ago.

All my .js files have this as the first line

import 	* as THREE 		from 'three';

And everything is working just fine !!!

But I can’t seem to figure out how “three” is being resolved.

That’s the question I am asking.



1 Like

There are 3 places where three can be coming from:

  1. If you’re using import maps - it’s you who tells the browser which module comes from where, like here for example.

  2. If you’re working with a bundler, three refers to the nearest available location of three module installed via npm. So if you have a project structure like so:

- project
  - index.js
  - package.json
  - node_modules

Bundler will first look for three in the node_modules directory.

If it’s not found there - depending on the bundler and the configuration, it may look for three in your global modules directory - place where npm installs modules installed via npm install -g - or traverse directories upwards in pythonesque-style until it finds node_modules that satisfies the project needs. (Though I honestly can’t remember if that’s a default behaviour, even if it would be - external modules would be something very risky to rely on, so it’s safest to keep dependencies in the same location as the project that depends on them.)

  1. If module path starts with a relative path indicator (ex. ./ or ../), bundler will look for the module / path only under that specific, relative path - and complain if the module is not found there.
1 Like

This is not how it works, you can’t import from a local three.min.js. The point of module resolution is that everything that imports from a namespace refers to the same module. The moment you import orbit controls or any third party package, which will import from “three”, it will fail.

That said, you could use import maps for that, but it shouldn’t be used for a similar reason. This is an unfinished browser specification that will bar you from most of the JavaScript eco system, which to a large degree is commonjs.

Webdev (with modules) has always functioned through bundling, if you consume three from npm (node package manager) you should use a tool that understands node modules and specifically package.json. The three docs have you use vite and that’s imo the most reasonable.

1 Like

It doesn’t failed on my apps, I still practice the old ways to carry the three.js on the apps folder, so i can manually update it when new update is available, this practice can save me from getting outdated when new release is available.

I used flexible map, using try catch when one option failed it used the next options and then the next if the seconds failed.

primarily I consumed three.js from npm, when offline the map failed triggering the next option pulling threejs from the browser’s cache.

1 Like

:ok_hand: While it’s definitely not a current “meta” way of doing things in web - what you’re doing is called vendoring packages - and is a great way of keeping things alive for a long time.

These days, attempting to run a 1 year old, unmaintained app with npm dependencies will 99.9% percent result in some dependency issues with gyp / binary deps / deep changes / poor semver, while a package with downloaded dependencies will always run the same way due to lack of external influence.

1 Like

no doubt it will somewhat work. you are still shut out of the eco system, can’t use published libraries. or, you go through hundreds of files, copy it here and there, and you’ll hack it. the churn involved is unreasonable since npm already tracks packages and can pin dependencies.

not to mention that all this is only for you to run a project locally. you could not publish, because your website would serve megabytes of data (three.min.js alone is 642 kb). if i visit your website on a commute and it will finally show up at the end of a one hour train ride, i much rather visit something else. you have maybe 3 seconds, if your site hasn’t loaded by then people will close the tab.

in essence, three has finally a sane approach on their website, everything else is imo a distraction.

indeed, thats right ensuring that threeverse app woks even after long time of no updates

threeverse loads quickly, threejs is not a movie file, and its still accessed as a library via the host so the loading pretty much similar to npm

it’s maybe hard to explain. when you load a library foo.min.js, say it is 800kb, and bar.min.js, say 700kb, and baz.min.js, say 900kb, plus your app that imports them, 30kb. then you’re throwing 2.43MB at the end user. this won’t load fast on mobile, nor is it similar to bundled npm.

imagine your app really only uses 5% of what’s actually in these modules. a bundler will pluck out the things that your app needs, this is called tree-shaking. a vite app will serve 117kb. what you do there, “vendoring”, is something that was abolished in the early 90s for a reason. after that came require.js, then commonjs and npm, which today is javascripts eco system, and this is where three gets pubslihed. we’re dealing with tools now that are incredibly easy and efficient, you don’t have to do anything anymore.

in the end, you use what you want, but hacking node packages is pretty odd to say the least, there’s no benefit you’re getting out of that.

1 Like

first, don’t take it in the wrong way, not doing this to win an argument or make you feel bad. perhaps it makes you think …

this is just the loading screen, on fast 3g TTL (time to first load, when you first see something) is 10 seconds, TTL (time to interactive, when you get to do something) is 30 seconds, it loads 5.5 MB of data. biggest module is ~600kb, most modules are uncompressed (everything you pull from three/examples), nothing is tree shaken.

the actual game, TTL 10 seconds, TTI 2.6 minutes, 28 MB of data.

in the end it’s probably 95% bigger and loads a 100 times slower than if you’d have used vite + tooling (image compression, model compression etc) …

really? whoa i didnt know it was that much data being downloaded, i will look into it, i made this threeverse 2 or 3 yrs ago during pandemic, tomorrow is my day off will dive into threeverse source and see how i can improve it by using npm.