GLTFloader fails in simple parcel 2 setup

I stripped my project down in this repo to illustrate the error I’m seeing when attempting to load a .glb file using GLTFloader.load().

I attempted to debug this by creating a breakpoint in dev-tools in chrome, then stepping through the code in GLTFloader.load. Stepping into lower level three code fails for reasons I can’t identify. Perhaps the source maps generated by Parcel aren’t correct.

With the test repo:

mkdir aDir
cd aDir
git init
git clone git@github.com:j13ag0/parcel-GLTFloader-test.git
cd parcel-GLTFloader-test
npm install
npm start

I lack the parcel (2) and Chrome dev-tools ninja skills required to suss out what’s happening.
Here’s what I see:

Uncaught TypeError: url.lastIndexOf is not a function
at Function.extractUrlBase (three.module.js:41130:21)
at GLTFLoader.load (GLTFLoader.js:156:31)
at loadData (main.js:25:16)
at run (main.js:9:5)
at Object.gLLPy.three (main.js:14:1)
at newRequire (index.4d6bcbeb.js:71:24)
at index.4d6bcbeb.js:122:5
at index.4d6bcbeb.js:145:3

I can’t tell if the problem is parcel related or otherwise.

Any suggestions would be appreciated.

-jg-

For those who understandably might not want to grab a repo, here’s what things look like…

package.json:

{
  "name": "parcel-GLTFloader-test",
  "version": "0.0.1",
  "private": true,
  "source": "index.html",
  "author": "jag",
  "license": "ISC",
  "staticFiles": {
    "staticOutPath": "./assets/models",
    "staticPath": "./assets/models"
  },
  "scripts": {
    "start": "parcel serve --open",
    "build": "parcel build"
  },
  "devDependencies": {
    "parcel": "^2.2.1",
    "parcel-reporter-static-files-copy": "^1.3.4"
  },
  "dependencies": {
    "three": "^0.137.5"
  }
}

index.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="/src/styles.css" />
    <script type="module" src="/src/main.js"></script>
</head>
<body>
    <div id="webgl"></div>
</body>
</html>

src/main.js:

import * as THREE from 'three';
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";

let scene = null;

function run() {
    loadData();
    //  main loop
    // console.log( "scene: " + scene );
}

run();

function loadData() {
    let gltfLoader = new GLTFLoader();

    let url = new URL( "../assets/models/cubeFish.glb", 
                   import.meta.url );

console.log("url:  " + url);

    gltfLoader.load( url, gltfFishReader, null, null );
}

function gltfFishReader( gltf ) {
    let fishModel = null;

    fishModel = gltf.scene;

    if( fishModel != null ) {
        scene = fishModel;
    }
}

.parcelrc:

{
  "extends": ["@parcel/config-default"],
  "reporters":  ["...", "parcel-reporter-static-files-copy"]
}

-jg-

I was also struggling with loading a glb file with three.js

For me this works, idk if it helps you but I had to look to other people code to understand what I did wrong and see how it maybe does work for you aswell. (im using a canvas in html)
For the whole file just email me: sacharveldhoen@hotmail.com

        new RGBELoader()
            .setPath('/environment/')
            .load('venice_sunset_1k.hdr', function (texture) {
                texture.mapping = THREE.EquirectangularReflectionMapping;
                texture.outputEncoding = THREE.sRGBEncoding;
                // scene.background = texture;
                scene.environment = texture;
                scene.environment.outputEncoding = THREE.sRGBEncoding;
                // loader

                const loader = new GLTFLoader()

                loader.load(
                    '/models/logo_vue.glb',
                    function (gltf) {
                        scene.add(gltf.scene);
                    },
                )
                // scene.background = new THREE.Color(0xffffff);
            });

Hi SachaVeldhoen:

To be clear, my experience with loading .glb files using GLTFloader has been successful.

The difference here is that I’m using Parcel 2 to bundle everything together.

regards,
-jg-

Ah ok i see now, my bad

The fix was to ensure that the url parameter to GLTFloader.load() is a String.

url = URL( someRelativeURL, import.meta.url );
url = "" + url;
gltfLoader.load( url, ... );

-jg-