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
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’;
/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.
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: