Can't get GLTFExporter imported into an angular component

Greetings,

Describing the bug

Thank you for this amazing library!

I got an angular project with the following information:

Angular CLI: 12.1.0
Node: 14.17.4
Package Manager: yarn 1.22.11
OS: linux x64

Angular: 12.1.3
... animations, common, compiler, core, forms, platform-browser
... platform-browser-dynamic, router

Package                         Version
---------------------------------------------------------
@angular-devkit/architect       0.1201.3
@angular-devkit/build-angular   12.1.3
@angular-devkit/core            12.1.0
@angular-devkit/schematics      12.1.0
@angular/cli                    12.1.0
@angular/compiler-cli           12.1.0
@schematics/angular             12.1.0
rxjs                            6.6.7
typescript                      4.3.5

THREE.REVISION :point_right: “127”

What I’m trying to build is a .gltf exporter for a specific type of file, namely .root for the organization that I’m currently working.
You can find the repo over here :point_right: link

Inside the file :point_right: /LHCb_WebDisplay/src/app/gltf-exporter/gltf-exporter.component.ts
I’ve tried to import the GLTFExporter.js file with the following ways:

  1. stackoverflow
// just for GLTFExporter
import * as THREE from 'three'
(<any>window).THREE = THREE;
import "three/examples/js/exporters/GLTFExporter";

/// on the method that I want to use it I implement the following
let options = {};
let exporter = new THREE.GLTFExporter();
exporter.parse(scene, (gltf) => {console.log("Parsed scene!"); }, options); 

The above should work based on this :point_right: link

But it’s not!

The error:

Error: export ‘GLTFExporter’ (imported as ‘THREE’) was not found in ‘three’
Error: src/app/gltf-exporter/gltf-exporter.component.ts:106:30 - error TS2339: Property ‘GLTFExporter’ does not exist on type ‘typeof
import(“/LHCb_WebDisplay/node_modules/@types/three/index”)’.
106 let exporter = new THREE.GLTFExporter();

  1. Then I tried adding a script tag directly to the index.html file then I manually loaded the functions from the GLTFExporter.js to my component.ts based on this :point_right: link

Even though with this method I didn’t get compilation errors, I got runtime errors:

ERROR Error: Uncaught (in promise): ReferenceError: GLTFExporter is not defined

  1. Then I tried the simpler way , which is similar to loading the GLTFLoader (which works by the way)
import * as THREE from 'three'
import { GLTFExporter } from 'three/examples/js/exporters/GLTFExporter'

let exporter = new GLTFExporter();
exporter.parse(scene, (gltf) => {console.log("Parsed scene!"); }, {});

/**
* Which again did not work,
* Even though doing the exactly same, but instead with GLTFLoader works...
*/

The error: (runtime again in the console, compilation is successful)

ERROR Error: Uncaught (in promise): TypeError:
three_examples_js_exporters_GLTFExporter__WEBPACK_IMPORTED_MODULE_1__.GLTFExporter is not a constructor

Keep in mind that I also got the following in my angular.json file

"scripts": [
  "node_modules/three/examples/js/exporters/GLTFExporter.js"
]

To Reproduce

Steps to reproduce the behavior:

  1. Go to :point_right: https://gitlab.cern.ch/anpappas/LHCb_WebDisplay
  2. git clone
  3. yarn install
  4. yarn start
  5. navigate to http://localhost:4200/
  6. click the gltf exporter button
  7. inside the codebase move to: /src/app/gltf-exporter/gltf-exporter.component.ts
  8. try any of the above mentioned ways of importing GLTFExporter.js
  9. ctrl + shift + i :point_right: check the console

Live

The repo lives live over here if that helps any further ( but it shouldn’t ) :point_right: link

Expected behavior

Have the GLTFExporter imported? :disappointed_relieved:

I’m not sure if this is a bug or my idiotness ( forgive me if it’s the latter ) but I would appreciate some help here!

Thank you for your valuable time.


P.S. Forgot to mention that I have succeeded into creating what I want into the following repository :point_right: repo

i.e. exporting my “special” .root file that describes a 3D geometry to .gltf with the GLTFExporter.js but as it is only a standalone html file with messy script tags and code inside I would like to properly merge it and refactor the code to a proper form into my angular application.

Thank you once again.


Platform:

  • Device: [Desktop]
  • OS: [Windows, MacOS, Linux]
  • Browser: [Chrome, Firefox, Safari]
  • Three.js version: [127]

Files in three/examples/js/* are UMD/CommonJS modules. If you’re using ES Module import syntax, you’ll want to use the versions in three/examples/jsm/* instead. I don’t know about angular specifically but a common import syntax would look like this:

import * as THREE from 'three';
import { GLTFExporter } from 'three/examples/jsm/exporters/GLTFExporter.js';

Thank you for your reply.

I’ve also tried all the ways that I mention in my text above both for the exporter into the js directory as well as the jsm.

Still nothing works.

Specifically speaking I’ve also tried what you mention and it is not working.

What’s the error shown with this approach? That is the right syntax for ES module imports.

I’m surprised it’s working for GLTFLoader and not GLTFExporter for sure…

Note that when using ES Modules you’ll reference it as new GLTFExporter() and not new THREE.GLTFExporter().

Hello @donmccurdy

Thank you once more for your answer and for your time.

So following your approach my code looks like this:

import * as THREE from 'three';
import { GLTFExporter } from 'three/examples/jsm/exporters/GLTFExporter.js';

/// this is a method inside my component
/// you should't care much about this
addGeometry(rootObj): void {

    var detector;

    ScriptLoader.loadJSRootScripts().then((JSROOT) => {
      JSROOT.require('geom')
                .then(geo => {
                   detector = geo.build(rootObj);
                });
    });
    
    /// but these 2 are the lines that we do care
    let exporter = new GLTFExporter();
    exporter.parse(detector, (gltf) => {console.log("Parsed scene!"); }, {}); /// detector is simply the 3D object that I want to parse

  }

I do compile the code and I get no errors.

On runtime though when I click a particular button in the application, that triggers the above method and thus the 2 lines concerning the GLTFExporter I get the following error:

ERROR Error: Uncaught (in promise): TypeError:
three_examples_js_exporters_GLTFExporter__WEBPACK_IMPORTED_MODULE_1__.GLTFExporter is not a constructor

I managed to finally make it work by following this approach: :point_right: stackoverflow

The link that I used to load the script for GLTFExporter dynamically in my angular component through the approach mentioned is the following :point_down:

<script src="https://cdn.rawgit.com/mrdoob/three.js/master/examples/js/exporters/GLTFExporter.js"></script>

Thank you once again very much for your valuable help and time!

You can mark this as resolved!

To import the GLTFExporter into an Angular component, you can use the following steps:

  1. Install the three packages using npm. You can do this by running the following command in your Angular project directory:

Copy code

npm install three

  1. Import the GLTFExporter class from the three packages in your Angular component. You can do this by adding the following line at the top of your component file:
    typescript

Copy code

import { GLTFExporter } from ‘three/examples/jsm/exporters/GLTFExporter’;

  1. Use the GLTFExporter class in your component as needed. For example, you could use it to export a 3D model in GLTF format by creating an instance of the GLTFExporter class and calling its parse method, like this:

typescript

Copy code

const exporter = new GLTFExporter();
exporter.parse(scene, (gltf) => {
console.log(gltf);
});

Make sure to replace scene with the instance of your THREE.Scene object.

If you’re still having trouble with importing the GLTFExporter, make sure to check that you’ve installed the three package correctly, and that you’re using the correct path to import the GLTFExporter class.