Skip to content
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

Starting from r109 three.module.js contain non transpiled classes #18007

Closed
GhassenRjab opened this issue Nov 26, 2019 · 17 comments
Closed

Starting from r109 three.module.js contain non transpiled classes #18007

GhassenRjab opened this issue Nov 26, 2019 · 17 comments

Comments

@GhassenRjab
Copy link

r109 introduced the usage of ES6 which is a good thing.

Reading the PR #17276 that made this change states that the classes get transpiled to ES5 syntax in three.js and three.min.js which is not sufficient.
three.modle.js needs to have ES5 syntax too.

In fact other NPM modules depend on three.js such as Photo Sphere Viewer that got affected by this change.

We use this module on production and it caused our website to crash on IE 11.

@GhassenRjab GhassenRjab changed the title Starting from r109 three.module.js contain non transpiled classes Starting from r109 three.module.js contain non transpiled classes Nov 26, 2019
@looeee
Copy link
Collaborator

looeee commented Nov 26, 2019

This is intentional. See #17919

@mrdoob
Copy link
Owner

mrdoob commented Nov 26, 2019

IE11 doesn't support ES6 so it needs to be transpiled anyway. We recommend you do that as part of the bundle for your project.

@GhassenRjab
Copy link
Author

I understand why now.

Thank you for the clarification and the advice

@srgpqt
Copy link

srgpqt commented Jan 14, 2020

@mrdoob The better fix that avoids all this issue entirely would be to provide three.module.js which should be plain ES5 with modules, and three.es6.js which would contain all the ES6 features you like to use.

three.module.js should not use class. It is not okay to expect module users to transpile the library themselves to support IE11.

This may be my personal opinion, but it seems to be the generally accepted view of most JS libraries I've encountered. I've never needed to transpile a modern third-party library myself to make it work with IE11. YMMV.

@mrdoob
Copy link
Owner

mrdoob commented Jan 14, 2020

IE11 doesn't support modules either.

@srgpqt
Copy link

srgpqt commented Jan 14, 2020

@mrdoob you are correct, and that's why users of three.module.js must use a module bundler like webpack, rollup, or parcel.

The idea is that three.module.js should be usable with webpack (or other bundler) without also bringing in babel or typescript to transpile Three.

@srgpqt
Copy link

srgpqt commented Jan 14, 2020

@mrdoob in case it isn't obvious, webpack and other bundlers can and do replace import/export syntax with IE compatible ES5 code

@mrdoob
Copy link
Owner

mrdoob commented Jan 14, 2020

Devs aiming to street IE11 can use three.min.js or if they use webpack they can bundle and transpile three.module.js. What am I missing?

@srgpqt
Copy link

srgpqt commented Jan 14, 2020

@mrdoob The point is not having to transpile three.module.js and also have the benefits of modern ES6 module syntax and webpack tree shaking.

Every other library I've ever used does this properly.

@mrdoob
Copy link
Owner

mrdoob commented Jan 14, 2020

With the current architecture, we can't have tree shaking without classes.

@srgpqt
Copy link

srgpqt commented Jan 14, 2020

It would still be nice to have just modules so that it can be used in a webpack project without having to setup an ES6 transpiler. Oh well, I tried. At least you are fully aware of the issue now, even if three.js continues to be a pain to use.

@looeee
Copy link
Collaborator

looeee commented Jan 15, 2020

Once you've already got a bundler running (Rollup, Parcel, Webpack) adding Babel is not that hard, so I don't see what all the fuss is here.

@dkurucz
Copy link

dkurucz commented Feb 3, 2020

@mrdoob @looeee the ask here is that Three.js follows suit on many established standards in the open source community to enable wide consumption of the library on all platforms. It is known across the community that not all browsers follow the ES6 conventions out of the box, the main offender used by a substantial set of web consumers being IE11.

By asking developers to manually transpile the final build of the library as a runtime, you are asking developers to provide an extra configuration that is entirely self-composed in order for their application to be able to consume it. From a pure practical sense in the context of Three.js, this is a perfectly valid ask, but from the perspective of developers working on larger scale projects, Three.js in all likelihood not the only library being pulled into the project. Imagine if every library on github started adopting this mentality. Every developer would need to provide a compatible configuration, often times a very fragile and high-maintenance project-level configuration, based on the ECMA standard of the sum of all libraries required, to correctly transpile. The number of libraries can get into the tens, hundreds, and this is only for direct dependencies. Furthermore, they would be required to check, update, and change every time each individual library updates in a breaking way. When transitive dependencies start coming into the equation, it gets even worse. What this amounts to is a maintenance task that should be entirely avoided, as the minimal configuration for any library to correctly work as ECMA evolves over time will absolutely vary between projects and dependencies.

In addition to all of this, each time a library provided a breaking update, a developer would not only need to anticipate that it updated, but the developer would also need to spend time understanding how those updates affect their existing configuration. This isn't a matter of understanding Babel at this point, it's a matter of maintenance over time for every library that follows this avoidance mentality, forcing consumers to understand what the project needs to work correctly, and then playing referee for the sum of all dependencies, some which might actually have locked in a version of Babel until a subsequent release (Vue's CLI and testing tools are a perfect example), which could actually trap them into pulling in multiple versions of Babel with multiple configurations. Out of the box, the library should work against the lowest common denominator runtime. Playing referee in this regard does not scale from a maintenance, time, and overall cost perspective, especially for small teams working on a limited budget who may rely on large numbers of libraries in order to be successful.

In an even mostly ideal world, the onus is on the developer of the library to provide some form of configuration that is guaranteed to work without requiring developers to spend time figuring out which Babel versions, configurations, and plugins are required for this specific project. Taking the responsibility as the browser ecosystem matures, you are able to alleviate, mathematically, potentially hundreds of hours at a time around domain-specific requirements that (may not yet, but will) exist for the library to ultimately work as you increment the version and adopt newer ECMA features, and you are able to guarantee that it will work the same way every time, since it will have worked prior to being pulled in to the consuming project. At the moment, you haven't even established which versions of any of the above you will need to configure (are you ES2015, 2017? etc). Given the long list of available standards, https://en.wikipedia.org/wiki/ECMAScript, any developer will need to start off by guessing what features you are consuming.

I hope you reconsider because of how widely Three.js is used. This is not an exhaustive list, but please understand that the open source community does in fact typically provide the common reduced library runtimes for a very good set of reasons.

@donmccurdy
Copy link
Collaborator

donmccurdy commented Feb 3, 2020

the ask here is that Three.js follows suit on many established standards in the open source community...

Are there references you could share explaining this standard? All npm packages should be published as ES5? They aren't always, as a rule, but I'm certainly open to any guidelines we can find.

Out of the box, the library should work against the lowest common denominator runtime.

Developers using threejs may be writing applications whose final build output targets different ECMA features, from ES3 up to ES6+. By transpiling the library down to older JS versions we may also force some costs (code size, performance) onto developers who are targeting modern browsers. three.js is an unusually performance-sensitive library, and there has historically been some aversion to adding new build steps that mutate optimized code.

I don't know whether those costs outweigh those you describe; perhaps not. But it would be nice to have input from authors of the bundling/transpiling tools here.

@mrdoob
Copy link
Owner

mrdoob commented Feb 3, 2020

So the ask is to provide a three.module.es5.js build so people can do tree shacking and we are responsible for the transpiling? Would a three.umd.js work too?

@donmccurdy
Copy link
Collaborator

donmccurdy commented Feb 3, 2020

I think the ask would be that both our pkg.main (CommonJS or UMD) and pkg.module (ES6 Modules) entries contain only ES5 code, excluding the ES6 import/export statements in the latter. If we wanted to also publish the original ES6 code, in this situation, it would have to be a separate npm package, like npm install --save three-es6.

EDIT: Although just putting a three.module.es5.js version into the published build/ folder — not in pkg.module — is definitely not a standard practice, that might work as well if that's what you're suggesting?

@mrdoob
Copy link
Owner

mrdoob commented Feb 3, 2020

EDIT: Although just putting a three.module.es5.js version into the published build/ folder — not in pkg.module — is definitely not a standard practice, that might work as well if that's what you're suggesting?

Yes, that's what I meant.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants