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

[WIP] Examples: Use ES6, build UMD examples. #13544

Closed
wants to merge 1 commit into from

Conversation

donmccurdy
Copy link
Collaborator

For #9562. I'm guessing this is more build process than we want, and no worries if that's the case, but I wanted to suggest this as an alternative to the other way around (write UMD, build ES6) because it has some interesting pros/cons.

I manually changed a couple examples to ES6 modules, then wrote a script to compile them to UMD modules. The UMD modules work in script tags or CommonJS. Build created as follows:

# build all
node examples/js/build.js 

# build GLTFLoader.js
node examples/js/build.js GLTFLoader

Pros:

  • Examples can be written like the rest of the library.
  • Examples can depend on other examples.
  • Examples can be bundled:
<script src="build/examples/js/nodes/nodes.js"></script>
import { NodeMaterial, InputNode } from 'three/examples/js/nodes/'

Cons:

  • threejs.org/examples/*.html must point at build/examples/js/*.js, and won't "just work" for testing PRs with RawGit.
  • Examples must be rebuilt with each release, or on some other cycle.

@looeee
Copy link
Collaborator

looeee commented Mar 12, 2018

I'm trying to test this, but getting an error:

>> node .\examples\js\build.js
rollup:
events.js:193
      throw er; // Unhandled 'error' event
      ^

Error: spawn rollup ENOENT

...

It seems like spawn is pretty hard to get working in a windows environment, in the end I installed cross-spawn and changed the spawn require to:

const spawn = require( 'cross-spawn' );

and it seems to be working.

@donmccurdy
Copy link
Collaborator Author

donmccurdy commented Mar 12, 2018

Hm I just looked through nodejs/node-v0.x-archive#2318. 😐 Using spawn('cmd', ['args'], {shell: true}) might also be a fix...

In any case I suppose the first question would be where (or if) we'd use a script like this. Ideas:

  1. Build UMD files in build/examples/* on dev branch with each release.
  2. Build UMD files in a branch like three-umd, perhaps with a bot.
  3. Use a separate repo, maintained by interested parties.
  4. ?

We use a bot to maintain A-Frame's dist/ folder, but it does clutter commit history a bit.

@mrdoob
Copy link
Owner

mrdoob commented Mar 14, 2018

What do you think about this approach?
#9562 (comment)

@donmccurdy
Copy link
Collaborator Author

Are you thinking of generating a single three.extras.module.js ES6 module containing all examples, while leaving the examples themselves as they are now? If there's a clean implementation I would be fine with that, but I worry it will need a fairly complex script to do properly. What happens with inter-dependent examples, like nodes?

import { NodeMaterial, RawNode, ... } from 'three/build/three.extras.module.js';

As one depends on the other using global THREE.* syntax, I'm not sure how an ES6 build is going to handle that. If that's the goal, we can solicit a proof of concept from the other thread.

I think these issues are easier to solve if the maintained copies of files are themselves ES6 modules, and we generate the UMD versions. I assume the problem there is that the live examples on the site will no longer work with normal <script/> tags? Perhaps there is a workaround allowing examples to keep working without a build step if we drop an ES6 module polyfill into each example page.

@looeee
Copy link
Collaborator

looeee commented May 26, 2018

I think these issues are easier to solve if the maintained copies of files are themselves ES6 modules, and we generate the UMD versions.

This is exactly the approach that we should be taking. There exists extensive 3rd party tooling for this process in the form of Babel, Bublé etc.
Working in the other direction, we're going against the grain, and not future proofing the codebase - and also, we'll need to create and maintain the converter script ourselves, which will be fairly complex.

I assume the problem there is that the live examples on the site will no longer work with normal <script/> tags?

This is a bit of a sticking point - the examples are the main testing ground for development, and they do need to stay in sync with any work done on the dev branch so that we can catch errors quickly. However, if we have a build script that converts the examples ES6 -> UMD, we could just use these generated files in the examples. Then we can create a script to watch the examples/js/es6 directory (or whatever we call it), and regenerate the UMD files on the fly.

@moroine
Copy link
Contributor

moroine commented Jun 5, 2018

threejs.org/examples/.html must point at build/examples/js/.js, and won't "just work" for testing PRs with RawGit.
Examples must be rebuilt with each release, or on some other cycle.

As I explained here we could use ES2015+ module syntax polyfill for old browser.

I made a POC here, using ES2015+ module syntax:

Live: https://rawgit.com/moroine/three.js/poc-example-es6/examples/misc_controls_orbit.html

I have tested on IE11 and it works. It requires some time to load because of babel transpilation but IMO that's ok considering the support of the module import in browser: https://caniuse.com/#feat=es6-module

@donmccurdy
Copy link
Collaborator Author

Closing to focus on #14803. :)

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

Successfully merging this pull request may close these issues.

4 participants