Three.js: Importing scripts from examples/ folder to npm

Created on 17 Oct 2017  ·  8Comments  ·  Source: mrdoob/three.js

Description

The problem. Currently, if I want to import a file from examples/js to my three.js project (bundled with webpack or anything else like this)
Let’s say I need OBJLoader. I have two ways:

1) Download the file to my project. Modify it (add require(“three”), add exporting data). - The problem is that this is really complex and is annoying when you have several projects. + when new version of three.js is out with latest fixes/changes - I need to repeat the process.

2) Second way is to search npm if it already has a such module - but there we have several problems:
- The script can be outdated / not compatible with latest version of three.js
- Some modules want you to wrap it with THREE: OBJLoader(THREE) - which breaks the use of features like tree-shaking

Solution

As a possible solution, we can wrap each js file in examples/ with UMD pattern. We would be still able to use it with THREE from global variable, and be able to include them with npm:

import OBJLoader from ‘three/examples/js/loaders/OBJLoader’;
Three.js version
  • [ ] Dev
  • [x] r87
  • [ ] ...
Browser
  • [x] All of them
  • [ ] Chrome
  • [ ] Firefox
  • [ ] Internet Explorer
OS
  • [x] All of them
  • [ ] Windows
  • [ ] macOS
  • [ ] Linux
  • [ ] Android
  • [ ] iOS
Hardware Requirements (graphics card, VR Device, ...)
Duplicate

Most helpful comment

True, and not ideal of course, but this is much easier to work around than copy/pasting files or using unofficial npm modules:

window.THREE = require('three');
require('three/examples/js/exporters/OBJLoader');

const loader = new THREE.OBJLoader();

All 8 comments

/ping @mrdoob @WestLangley @Mugen87

There is a (much, much) longer discussion: https://github.com/mrdoob/three.js/issues/9562

Although FWIW, this pattern works just fine with Browserify. I think the problem is only when using newer ES6 module import syntax?

@sasha240100 If you don't mind, i'd like to mark this issue as a duplicate. Like @donmccurdy said #9562 is the leading discussion for this topic.

@Mugen87 Yep, sure.
@donmccurdy That works only when you have global THREE set. However, you can't make it work like this:

const OBJLoader = require('three/examples/js/exporters/OBJExporter');

True, and not ideal of course, but this is much easier to work around than copy/pasting files or using unofficial npm modules:

window.THREE = require('three');
require('three/examples/js/exporters/OBJLoader');

const loader = new THREE.OBJLoader();

@donmccurdy The thing is that what if we're using tree-shaking. Now we're forced to include all Three.js library even if we need only a specific part.

If you need to tree-shake the core three.js library then you're right, there is no way without modifying the example/* file or finding a (probably out of date) copy of the dependency on NPM. https://github.com/mrdoob/three.js/issues/9562 would be the discussion to track for proposed solutions, but it isn't solved yet.

As said @donmccurdy, there is no solution without modifying files under example.

My solution to allow tree shaking for example files, is to use gulp to convert ( with some find/replacement ) example file to ES6 module, nd put them into a temp folder. In that way you will be able to use any example file to the cost of some line of code under a gulp task to convert them into es6 module.
I know to that in the #9562 some people had make some convertor like this, you should take a look or implement your own.

If you're using gulp that could be a good solution, and you will be able to import only what you need before any tree shaking, without any npm repo.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

seep picture seep  ·  3Comments

donmccurdy picture donmccurdy  ·  3Comments

fuzihaofzh picture fuzihaofzh  ·  3Comments

zsitro picture zsitro  ·  3Comments

clawconduce picture clawconduce  ·  3Comments