How to get GLTFLoader work in browser (Typescript + Three.js)

Hi.

I’m a noob to JavaScript and Three.js. Sorry for a long post.

TL;DR I managed to hack together working thing using JS and Three.js. So far I had an simple index.html where I had script tags for Three.js and GLTFLoader, then a script for my code that loaded glTF model for display. Converting this to TS is the issue, I can’t get imports working, and I’m also lacking info how to make TS version run in browser…

JS to TS
When I tried to convert this mini project to Typescript (while learning TS), I got stuck. I don’t know if it is even possible to convert TS into JS that works in browser by just doing “tsc” to compile files into JS. When trying to compile TS files into JS, and then open the index.html page (that points to compiled js) from browser, I get errors that require doesn’t exist, which led me to thing that TS can’t actually make working JS+html compo with just by running tsc. I haven’t found any proper articles that would give general overview on this topic only some esoteric problem descriptions and articles that are way above my understanding on this topic.

After going through official TS intro pages, I noticed in their Gulp tutorial they used Browserify (which I was not familiar with) to somehow package the TS code into one file that browser can understand. I followed the tutorial, and for simple TS files this seemed to work just fine, resulting in html page + JS that ran without errors. But this didn’t work for my TS files that had imports for THREE.js;

1. General import errors.
First I had errors with local copy of Three.js. I just copied the three.js file into project folder. However when I tried importing it with:

"import * as THREE from 'threePathHere';

I got errors in code, like THREE wasn’t even there (not possible to access functions of THREE.*). Then I swapped to version in Node npm package repository, and now the import seems to give no errors.

2. The GLTFLoader doesn’t seem to want to cooperate.

import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';

And this seems to be no-go - trying this gives no error, but when trying to compile with browserify, I get error about GLTFLoader:

SyntaxError: 'import' and 'export' may appear only with 'sourceType: module' (9:0) while parsing PATHHERE\GLTFLoader.js while parsing file: PATHHERE\GLTFLoader.js

Seems like the issue is somehow related to using these JS files in TS project, yet I don’t have any means yet to spot what is going on…

Questions:
Do I actually even need browserify, can I somehow avoid whole bundling thing? Just JS + html?

Can I actually import THREE or any other similar libraries to TS project with import?

Any pointers and general explanations would be helpful!

I’m not using TS but I can tell you than it does not run natively in browsers. So you have to compile it into JavaScript in your build process before you can actually execute your application. Maybe you find some useful information in the following topic:

Hi, and thank you for the reply. Like I said, I’ve done the compile with tsc, I get the js files, and any generic example will work fine in browser.

The link - I already actually saw that discussion. I also at least tried the moduleResolution:“node” thing, and it didn’t help. Was there something specific you meant in that page I missed?

Edit: I think my key issue here is to know is it even possible to run JS generated by TS “as is” from html page, or do I have to use some packager like Browserify, to be able to run Three+glTFLoader… which leads to me getting errors in running Browserify.

BTW. This page (bottom of the page) describes how modules (like GLTFLoader?) can be imported. Seems like this works only for JS projects then? This is what I used too…

https://threejs.org/docs/#manual/en/introduction/Import-via-modules

This is the exact line I have now:

import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';

And this will error when trying to run Browserify manually like this, on tsc generated JS files:

browserify build/main.js -o build/bundle.js

However, I just modified this from Browserify’s main page example, no idea if there are some settings.

Although the project provides type declaration files for the entire code base, the focus of three.js is clearly on JavaScript. Hence, most tutorials and guides are not in context of TypeScript.

Hence, I’ve asked for an experience TS/three.js user to provide a new guide in the official documentation in order to make users the startup with TypeScript easier. Unfortunately, nobody has contributed this task so far :frowning_face:

1 Like

I had the same problem and the developer of a GLTF wrapper kindly informed me that there are precompiled versions of the loaders in the ThreeJS repo in the js folder. I was using the jsm folder too:

three/examples/jsm/loaders/GLTFLoader.js

The compiled ones are in:

three/examples/js/loaders/GLTFLoader.js

If you include those files the same way you do for three.js in the Typescript file, you can access the loader using THREE.GLTFLoader.

I just concatenated/minified a few of the loaders into a single file and did the same for the corresponding d.ts files in the jsm folder and it works great for me in Typescript.

Thank you. I think I already tried that, and I now tried this again. If i write THREE.GLTFLoader, I get red squiggly line… as the VS Code can’t find loader (even if trying to use the version from /js folder). I can make it work by compiling with errors, but it won’t work with scripts… as those will give error about missing GLTFLoader. I guess you have done something better.

That concatenation/minify thing sounds interesting, I have no idea where you put those and how to reference those so I wouldn’t know how to start.

You need to have the d.ts files from the jsm folder in your project for the corresponding files you use in the js folder. Typescript uses the d.ts files to get rid of the red lines as that’s where the classes and types are defined.

I forgot to mention you need to add the module to the d.ts. You can merge the files manually by just copy pasting them into a single file one after the other.

  • create a file and copy paste the contents of however many loaders you want from the js folder. GLTF also reference the Draco loader and DDS loader.
    Save this file as something like three-loaders.js

  • create a file and add the module declaration for ThreeJS
    declare module THREE {}
    Inside the brackets, paste the d.ts files from the jsm folder for all the loaders you used from the js folder.
    Save this file as something like three-loaders.d.ts

Include the js and d.ts files in your Typescript project the same way you do for three.js.