I was very happy to see that in r105 there are now modules that can be easily imported. Sadly this results for me in having three.js twice in my final bundle (at least that’s what I think).
My current pipeline is
Writing stuff in TypeScript
Gulp with tsify, babelify and then browserify to get the code running again in the browser.
In order to bundle the file with browserify I need to jump back to es5 syntax which might create my problem. My new bundle is now almost twice the size and experiences the same problem as described here: https://github.com/mrdoob/three.js/issues/6362
Example import:
import { Scene, Group, PerspectiveCamera, CubeTexture, Object3D, AmbientLight } from 'three';
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
When not doing the import of jsm files the problem does not occur. I’m wondering if there is a way to use the jsm files with browserify, or if there is another way to import them in a clean way.
It seems this issue only happens with TypeScript. I’ve provided a sample repository at the end of the linked topic that demonstrates a project setup with JavaScript and rollup that produces a build file without duplicates.
Still, it’s somewhat unfortunate that this happens with TypeScript. Unfortunately, I’m not using Typescript so I’m unable to explain why three.js gets included twice.
I believe our problem had to do something with the “separate” nature of modules inside three/examples/jsm/. We were/are using several modules from this direcory : Sky, OBJLoader, SubdivisionModifier & PMREMCubeUVPacker + PMREMGenerator. After doing this our bundle size was okay again (not double) + we had no issues with the geometry.id s any more.
All other three/src modules described inside src/Three.d.ts (means not inside the three/examples/jsm folder) didn’t cause any trouble.
Yes, when I don’t include any of the example files the problem does not occur. If you use babel you can kind of foce the source of threejs with .require(require.resolve('three/build/three.module.js'), { expose: 'three' })
This does solve the duplicate problem, but now I need to run babel on whole of three.bundle.js in order to get it es5 ready. This takes up quite a lot of time. I’ll try doing the same to get my bundle time down.
@Mugen87 Thanks for the links! I guess it has to do with the resolution of normal three imports (which probably point to build/three.min.js and the resolution of jsm files (which point to build/three.module.js). This is just a guess though, I don’t know how to prove that.
@cream So I tried to follow your solution as well to avoid long compile times. I don’t know about your pipeline, are you using browserify? I just bundle after tsify I will get the following error: SyntaxError: 'import' and 'export' may appear only with 'sourceType: module' (9:0) while parsing
Totally makes sense, since browserify needs es5 code, so imports are not allowed.
If I use babel to transform the file, I’ll get ReferenceError: Unknown option: .extensions. Check out https://babeljs.io/docs/en/babel-core/#options for more information about options. while parsing file: C:\project\src\three-examples\loaders\GLTFLoader.js
Not quite sure why that happens, .extensions is quite often in the GLTFLoader.js
@JohannesDeml We’re developing with a TypeScript + Rollup.js (code splitting modules / no modules) setup, not using Browserify or Babel, see configs here.
I should have been more precise. Not really the module, but babel when trying to convert everything to es5. I have this theory since pointing everything to the model solves the problem for me (.require(require.resolve('three/build/three.module.js'), { expose: 'three' })). At least that’s what I think it does.
I see, thanks a lot for the info. I haven’t tried rollup yet, but it seems like a good solution!