Loading assets from webpack?

SceneLoader.LoadAssetContainer() only accepts a string filename or a File, for the asset.
How then to instruct Babylon to load a scene from webpack instead?

This is a demo showing how to use webpack’s url loader to convert a model and use this string to load the model:

RaananW/babylonjs-webpack-es6: Babylon.js basic scene with typescript, webpack, es6 modules, editorconfig, eslint, hot loading and more.

Hi Raanan,

Your demo works for me, specifically the scene loadModelAndEnv.ts which loads a glb and which is what Im struggling to do. But I cant seem to replicate what you’re doing.

Ive configured Webpack to load .glb same as you do:

            test: /\.(glb)$/,
            use: [ {
                loader: "url-loader",
                options: {
                    limit: 8192
                }
            }]

I import my asset the same way as you, using import and not webpack’s dynamic import():

import pf2 from “…/assets/KMP1023.glb”;

And then I load the asset into BJS same way as you (synchronously in my case, for simplicity):

const result = SceneLoader.ImportMesh( “”, “”, pf2, scene, undefined, undefined, undefined, “.glb” );

But BJS just hates me. With the url-loader limit set to 8192, the import returns a webpack asset filename:

/97339f07432e1b91cbef1cc4897aa637.glb

which gets me:

logger.js:47 BJS - [18:11:57]: Wrong sceneFilename parameter

Looking briefly at the BJS loader code, it seems to hate the leading / but stripping that only leads to BJS trying to generate a fully-qualified URL that is clearly not referencing webpack and only 404s.

Changing webpack config removing the url-loader 8192 limit, the import result seems useful:

data:model/gltf-binary;base64,Z2xURgIAAADY1RcAfEQAAEpTT05…

but still the BJS loader chokes:

Unable to find a plugin to load .glb files.

Ive gone in circles with every tutorial and forum post I can find. Any insight into what Im doing wrong?

I just spoke to BJS, it doesn’t know what you are talking about. BJS loves everyone! :slight_smile:

Let’s deal with both issues -

You will need to set the base URL to the public directory where webpack stores your files. Then you will need to only use the .glb file.

This is probably because you don’t include the @babylonjs/loaders package, or didn’t import the gltf loader from the loaders package. Documented here - Babylon.js ES6 support with Tree Shaking | Babylon.js Documentation

1 Like

So 3 things:

  1. Import the loader for its side-effects! I didnt realize that’s how it worked, derp. Thank you. The base64-encoded import via url-loader now works.

  2. With that fixed, I was able to fix my Webpack asset path, so that BJS now also loads the webpack asset filename case as well.

  3. The remaining trickery was in understanding that when an import returns a Webpack asset filename and NOT a data: URL, the filename includes a path ("/") which is redundant with SceneLoader’s rootUrl and needs to be separated.

Warning for future BJS n00bs like me:

SceneLoader does not like the import return value from Webpack as-is, in that particular case. Split the path from the filename.

import pf2 from “…/assets/KMP1023.glb”;
let file = pf2.replace( /^//, ‘’ );
const result = SceneLoader.ImportMesh( “”, “/”, file, scene, undefined, undefined, undefined, “.glb” );

(Or probably better yet, split the path component off and then re-use it as rootUrl, in case it ever varies from plain old “/”).

Oh, this is all about setting webpack’s output and public path. It does like any URL, but it really does depend if the URL is available at the current base or a different base.

I am very glad it all worked out.