-
-
Notifications
You must be signed in to change notification settings - Fork 35.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enable tree-shaking both for the main and examples files #16301
Conversation
@@ -7,6 +7,7 @@ | |||
"jsnext:main": "build/three.module.js", | |||
"module": "build/three.module.js", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It'll be a problem if the module
entry is build/three.module.js
but the JSM example files all import from src/Three.js
. In this case...
import { Vector3 } from 'three';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
... GLTFLoader will create Vector3 instances that are not the same as the Vector3 instances from three
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice catch!
My objective was to find a solution for people who already import the main three.js from the src/ folder for the tree-shaking to take effect, like this:
import { Vector3 } from 'three/src/math/Vector3';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
Currently if they do that for the examples/jsm
the whole bundle will be imported as well.
Is there a way we can achieve this in your opinion?
In #16220 we're considering converting the examples to use However if we do this while importing from |
@looeee I didn't know about those plans, you're right, three.js needs to be imported as a bundle in the esmodules examples. So how would we go about importing
without importing the whole bundle like we do with
|
Hmm, I can't think of any easy way around this right now. We either get easy tree-shaking (but Webpack only, I think?), or we get to convert the examples to use I'm inclined to think that converting the examples is more important, and it's up to people to get tree-shaking working in their own apps. They would need to do this: import { Vector3 } from 'three/src/math/Vector3'; // from NPM package
import { OrbitControls } from './local_dir/OrbitControls.js'; Then in the local copy of import {
EventDispatcher,
MOUSE,
Quaternion,
Spherical,
Vector2,
Vector3
} from "../../../build/three.module.js"; to import from the various |
You're right, webpack should tree-shake the I'll make a separate PR for the |
Happy easter everyone!
The aim of this PR is to optimize the repo in order to enable tree-shaking for the webpack users so all of the non-necessary three.js code isn't included in the final bundle.
All the heavy work is done by the property
"sideEffects": false
in the package.json, which is saying there isn't any shared "state" in three.js which is affected by other non-required files. This is true since three.js' core uses only import/exports and isn't using any non-imported module (correct me if I'm wrong).More info here
With this, importing any component from the main
Three.js
file won't include all of the non-executed components in the bundle anymore, for exampleBefore:
After:
Even better importing three.js
* as THREE
will still be tree-shaked and include in the bundle only the properties which you use in the code:Becomes:
Here is a test-repo if you want to test this out: three-test.zip
For the
examples/jsm
files instead, I updated the imports from"../../../build/three.module.js"
to"../../../src/Three.js"
, the tree-shaking takes care of the rest. This is because the filethree.module.js
cannot be tree-shaken since all the code is in the same file. (If anyone has more insight on this please share)Here is a test:
Before:
After:
Finally I added
"prepublishOnly": "node utils/modularize.js"
to the package.json just to make sure the jsmodules are always up-to-date.