React, Vue, and Nuxt can't import meshes in babylonjs@5.0.0-alpha

Hello,

I’m working on a babylon project in a Nuxt.js environment. Because of another bug, I had to switch version and use the preview package for 5.0.0-alpha.22.

I needed to import a local .glb object and it worked all well in version 4.2. But with the new 5.00 alpha, the console throws a parsing error : SyntaxError: Unexpected token g in JSON at position 0
image

I have checked and my exact same code works just fine when I use the v4.2 instead. Also the alpha 5.00 version is actually working when I am just using a 2-file project (index.html + script.js) with CDN’s, without any framework.

My attempts show that the very same error is thrown in Vue.js, on which Nuxt.js is based, but also on React.js, another popular front-end framework.

So here are the steps to reproduce the issue (using Nuxt.js, tell me if you need steps for Vue or React)

  • Create a new nuxt project using npm :
    • open a terminal and type npx create-nuxt-app my_project
    • pick npm as your package manager when prompted, hit enter to skip the other options
  • Place a working file test.glb in 'myproject/static/'
  • Download the mandatory dependencies :
    • npm i vue-property-decorator vue-class-component
    • npm i babylonjs@5.0.0-alpha.22 babylonjs-loaders
  • Check your nuxt project actually works using npm run dev and opening your localhost
  • Find the homepage template at 'myproject/pages/index.vue' and replace all its content with the code from this code paste.

Here are the screenshots of the code (couldn’t find a way to format the code inside my post) :


Hope to get some insights, it seems like a bug to me since the code works fine in v4.2, so the test.glb file is working and the file path is correct as well.

Don’t hesitate to ask for precisions ! :slight_smile:

This error usually shows up if you don’t load the loaders package. Are you including the loaders package in your build?

(EDIT :-)) AND - have you tried using the es6 packages instead of the UMD packages? they usually play much nicer with modern frameworks.

Hi @RaananW , thanks for your answer ! I’m not sure to understand what your idea is, though.

I have followed babylon’s documentation about importers, about loaders, and as I mentioned in the steps to reproduce, I am installing the npm package babylonjs-loaders and importing it in the code as an ES6 module with import 'babylonjs-loaders' (as described in the github’s readme)

Also note that the error log is very similar to a generic parsing error saying SyntaxError: Unexpected token < in JSON at position 0 which I believe is the error you get when you forget to import ‘babylonjs-loaders’, but this is NOT what is happening : the unexpected token is a "g" and not a "<", and it’s the first time for me that I encounter that.

My suggestion is to use these packages:

Babylon.js ES6 support with Tree Shaking | Babylon.js Documentation (babylonjs.com)

instead of the older-style UMD packages (which are more browser-ready than framework-consuming-ready).

That’s because a glTF file’s header starts with a g. The first character in the file is g - the file is loaded correctly, but the loader is not there, or not being used.

Having said that - it is possible that the loader is there, but the file’s extension is not present and babylon can’t decide which loader to use, so it is using the default one. I do see that the file is loaded as test.glb, but just to be sure, try to set the plugin extension (i think it is the 6th or 7th parameter of ImportMeshAsync) to .glb . If you can, also check (before loading) the the loaders are actually there. The simplest way to debug would be to console.log(BABYLON.SceneLoader.GetPluginForExtension('.glb')). If it’s defined the plugin is there.

1 Like

But I am using Nuxt.js. Like all the modern javascript frameworks, it is built on Webpack or Babel and uses ES6 modules, recognizable with the syntax import * as BABYLON from 'babylonjs'.
UMD would be using something like < script src="libs/babylon.js">< /script > Or am I completely wrong ?

I think you’re onto something there. I have logged your line in the console for both the v.4.2 and the v5.00 and I am getting different outputs. I’ll have a closer look and post more about this lead later in the evening !

Trust me, the packages you are using are the UMD packages :slight_smile:

Webpack simply knows how to consume them, but they are one huge package of code, supporting AMD and commonjs, and populating the global namespace.
I would recommend you to use the es6 packages, but it’s of course up to you.

Okay, so the log for GetPluginForExtension(’.glb’) doesn’t output “undefined” in either cases.
Specifically, when I logged it in the v5.00 I got this :


This is the same exact output I got from the v4.2 after I uninstalled the babylonjs-loaders package.

But in the v4.2 with the loaders, I got this output :


So it seems that my babylonjs-loaders import is just ignored after all in the v5.00.

So I’ll be trying to dig deeper into the ES6 package, but I’m not sure how to proceed, since a lot of the steps described in the doc you sent are not doable in my case. The doc explains how to build a babylon project using webpack from scratch with a bare npm init, but I already have an entire nuxt folder structure around it. I’ll check that out more thoroughly tomorrow.

Thanks again for your help @RaananW :slight_smile:

Okay, so I think I just tried out the actual ES6 packages.
I removed my previous 'babylonjs' and 'babylonjs-loaders' and instead I installed @babylonjs/core@5.0.0-alpha.23 and @babylonjs/loaders.

I then import them using :
import * as BABYLON from '@babylonjs/core/Legacy/legacy'
import '@babylonjs/loaders/glTF'

But I got the same error log : SyntaxError: Unexpected token g in JSON at position 0
And when I want to log GetPluginForExtension('.glb'), I got the same output than above (the first of the two screenshots), which seems to be the default loader with only extensions:".babylon"

So I still don’t get why, but the loaders package and import are simply ignored.

[EDIT] @RaananW Just noticed you’re the author of the babylon-ES6 boilerplate. I’ve tried the import with a clone of your repository and it does work just fine. So the issue must lie somewhere in the way the framework handles the packages import, which is bad news for me…

if you want to share a repository we might be able to dig into the code and see what’s up there.

I wouldn’t use the legacy interface, but @babylonjs/core directly. you can import the classes you ned (and thus enabling tree shaking), and have a cleaner version of your code.

If you do have the .glb loader, you can set it as default. it’s a hack, but will probably fix your issue. It’s not a solution though. it will only override the issue…

Hey back !

So I’ve set up a repository with a minimal Nuxt set up on github

I have changed my import to follow your advice, I guess it’s generally a good practice although it didn’t solve the issue of course.

The readme explains where to find the babylon code and how to run the nuxt project.
I installed both the UMD package and the ES6 package on purpose, to easily toggle the commented imports, since there are issues on either.

So with the UMD packages, the original error comes up with the unexpected token when trying to parse the glb file.

With the ES6 package however, I can’t even build, and I am not sure why, I’m still looking into it. The error looks like this :

How would I set the default loader, if I wanted to try this out ?

I’ll check the repo when I get the chance. Awesome :slight_smile:

An example on how to achieve this:

BABYLON.SceneLoader.GetDefaultPlugin = () => {
        return BABYLON.SceneLoader.GetPluginForExtension('.glb')
    }

Another way:

BABYLON.SceneLoader._registeredPlugins['.babylon'] = BABYLON.SceneLoader._registeredPlugins['.glb']

But those are … ugly hacks :slight_smile: I wouldn’t recommend them in production.

Alright, I’ll remember that.
I think I’ll wait to read your feedback though in case I missed some cleaner and obvious way to solve this, I need to get going on some other fronts in the meantime.
(also I think that the plugin for .glb extension is not actually found in my case)
Thanks for your tips !

A quick look at your package.json - the loaders and core packages need to have the version, otherwise it won’t compile correctly. Try changing both to be the same (^5.0.0-alpha.23)

1 Like

I think you nailed it ! Must confirm tomorrow and I’ll validate the answer. :smiley:

Alright, so it turns out that the versions were the problem ! That was why my loader was being ignored.
Having the same version on 'babylonjs' than on the plugin 'babylonjs-loaders' fixed my issue.

I couldn’t check that the fix also works with ES6 packages because of the error I sent above, something about not importing the ES module correctly, but I assume it’s another problem and isn’t related to the issue I had.
I would be interested in solving it too, though, I’d like to use the latest format for packages as you suggested. The issue is reproduced in the repository I sent, you just have to uncomment the ES6 imports in index.vue.