Three supports es6 modules, including a rollup, three.module.js. It does not provide a minified version, however.
This is a feature request to include three.module.min.js in the distribution.
The lack of three.module.min.js may be a result of the popular minifiers initially not being able to minify es6. This is no longer the case, see: butternut/squash https://github.com/Rich-Harris/butternut. Also uglify-es is a version of uglify-js that can minify es6+.
See the unpkg dashboard: https://unpkg.com/[email protected]/build/
Actually, I think this is a fair thing to ask.
We have changed all the examples to use three.module.js
. For a newbie, a three.module.min.js
would be the next step to reduce the bytes on their project.
Not everyone wants to dive in the rabbit hole of bundlers.
Closure Compiler says that it supports ES6 as output too?
https://github.com/google/closure-compiler/wiki/ECMAScript6
That seems pretty nonstandard to me; better practice is for users to do minification after tree-shaking in their build. The subset of users who are going to copy/paste scripts without a build step AND use ES modules is diminishingly small, and I think we can avoid adding a new build artifact for them by recommending CDNs like JSDelivr and Unpkg instead. JSDelivr provides minification automatically:
... we could provide .module.min.js
file ourselves, certainly, but most projects don't, and it would complicate the build process to do so for examples/jsm
, which users are presumably using at least some of.
That seems pretty nonstandard to me; better practice is for users to do minification after tree-shaking in their build.
+1 for this. We'll just be adding complication to the build while directing inexperienced users to use the library in a sub-optimal way. Non-minified code works fine, it's just not production-ready. Inexperienced users will need to work out how to minify their code for production at some point, so I don't see the need for hand-holding here.
Context from #17276:
@Rich-Harris wrote:
Essentially, the only browser that doesn't support class natively (with usage that isn't a rounding error, at least) is IE11. Which means that if you transpile ES2015 down to ES5, you're penalising (with a larger build) the 98% for the sake of the 2%.
I'd advocate for leaving class untranspiled, and maybe having a separate three.legacy.js build that is transpiled, where it doesn't matter so much about the extra bytes.
@mrdoob replied:
That's kind of the plan. three.module.js is ES6 with modules/classes. But we're trying to produce the same three.js and three.min.js we currently have.
I replied:
Should there also be a three.module.min.js, then, to serve as the new standard save-bandwidth build?
Then the discussion was moved here. My reply was intended as part of the quoted discussion, so then I copy the above discussion here too, hoping that this issue can contain a more general discussion about builds.
I think as said above, most of us use the ES6 version uncompilled so then our three shaking could only import what we're using (it's not working at the moment, but that's not the point of this reply).
What would be the use case for a three.module.min.js? It would be harder for you to debug errors if you import a minified version of a library while developing. Are you thinking of using three.module.min.js as a module in your html? or are you thinking of having a bundler like webpack, rollup, whatever, to bundle your project which uses three.js?
Are you thinking of using three.module.min.js as a module in your html?
Yeah, I think @mrdoob is referring to beginners how implement their code similar to the examples within a <script type="module">
tag (and do not use a bundler or build process).
I think beginners who base their development efforts on copy-paste from the examples will not benefit from the examples using a minified version, since that is harder to debug, and will not necessarily benefit from the mere existence of a minified version either, when that is not enabled in examples by default. Hm.
when that is not enabled in examples by default.
Some context: Using the unminified version of three.js
in the examples was done with this PR: #8413 (also have a look at the related issue)
The essence of my digging into that reference, is @bhouston asking:
I wonder if we should have the examples load three.js to make them easier to debug?
followed by @WestLangley agreeing and making a PR.
I've experimented a bit with with three.module.min.js
and it seems the project will introduce a major issue if this build artifact is provided. Consider the following setup:
import * as THREE from "https://cdn.jsdelivr.net/npm/[email protected]/build/three.module.min.js";
import { OrbitControls } from "https://cdn.jsdelivr.net/npm/[email protected]/examples/jsm/controls/OrbitControls.js";
As you can see in this live example, the setup will import three.js
twice. The app loads three.module.min.js
but also three.module.js
since OrbitControls
like any other example module internally points to it.
Hence, providing three.module.min.js
will only lead to duplicate imports and thus undefined behavior in user level code. It really seems better if code minification is handled on app level as part of a proper (node.js based) build.
@mrdoob I would say this issue can be closed. The concept of having a minified core build is not appropriate in context of ES6 modules. Code minification/obfuscation needs to be handled on app level.
@Mugen87 Agreed!
Most helpful comment
Actually, I think this is a fair thing to ask.
We have changed all the examples to use
three.module.js
. For a newbie, athree.module.min.js
would be the next step to reduce the bytes on their project.Not everyone wants to dive in the rabbit hole of bundlers.