Hello everyone!
First time for posting anything here, so I hope it’s the correct channel.
tdlr:
I can’t use import {Meshbuilder} from babylonjs with import {GridMaterials} from '@babylonjs/materials because when I try to add the gridMaterial, Typescript is throwing the error that 128 properties are missing to assign a GridMaterial to ground.material.
I wrote an example repo with some “starter-like” setup of the current configuration we have in our project. We use NextJS, the latest Babylon 6.11.2.
We would like to use the import style 'import { Scene, Meshbuilder } from “babylonjs” ’ in our project and were happy with it so far.
We used in a older project the GridMaterial and wanted to use it again. But the Material get’s importet with “@babylonjs/materials” and expects “@babylonjs/core” to be installed too. Even if I add the core ( basically double ) I got typescript issues, that the GridMaterial cannot be assigned to ground.material.
I tried a whole day and couldn’t make any version work.
Please share any suggestions here, or on github directly. Thank you!
So, mixing UMD (the babylonjs-* style packages) and ES6 (@babylonjs/* style) is not recommended, from my understanding, they work in completely different ways and having both styles in one project won’t work, as you’ve already seen. But since we build the entire project for both styles, you should be able to get everything in UMD, and GridMaterial should be available in babylonjs-materials - npm (npmjs.com) which is the one you’ll want if you want to use the UMD core. If GridMaterial is not available there then please let us know and we’ll fix it asap
import {GridMaterials} from ‘@babylonjs/materials’
are both ESM and should therefore work together? Sorry I never did a deep dive into the different js import possibilities and just assumed that everything with ‘require’ is UMD and ‘import’ is ESM.
If my assumption is true, then this code snippet should work?
import { Scene, MeshBuilder } from "babylonjs";
import { GridMaterial } from "@babylonjs/materials";
const scene = new Scene(engine, { useGeometryUniqueIdsMap: true });
let gridMaterial = new GridMaterial("grid", scene);
Currently that combination does not work (without even running it, just building it)
Error:
import { Scene, MeshBuilder } from "babylonjs";
import { GridMaterial } from "babylonjs-materials";
const scene = new Scene(engine, { useGeometryUniqueIdsMap: true });
let gridMaterial = new GridMaterial("grid", scene);
It’s a bit confusing to get used to I agree, Javascript has way too many ways of doing things
require vs import is a bit different than UMD vs ES6, the former relates to the way of, well, importing/bringing modules into your code, while the latter is the way the modules are organized internally. I asked Bing to elaborate on the difference between require and import and it gave a nice summary:
In summary, UMD is a pattern that allows modules to work in different environments, while ES6 modules are a new standard for defining and importing modules in JavaScript
Hope this helps clear up things a bit, feel free to ask if you need any more clarification
A big thanks for the long explanation!
We definitely want to go with ESM for Treeshaking. Thanks also for the provided ES6 Link, I did not stumble upon that before.
Then on to a new “problem”. I switched for all imports to @babylonjs/core and @babylonjs/materials.
Now I need to import the previously used debug layer as it’s own package with @babylonjs/inspector right? After I imported that, I got the message that a few more dependencies were missing. So I added manually with yarn, all dependencies until the warnings stopped.
then I followed the instructions on the documentation for the inspector:
But in the end I still got some importing error.
The currently used code snippet would be:
import { Engine, Scene } from "@babylonjs/core";
import "@babylonjs/core/Debug/debugLayer"; // Augments the scene with the debug methods
import "@babylonjs/inspector"; // Injects a local ES6 version of the inspector to prevent automatically relying on the none compatible version
import { GridMaterial } from "@babylonjs/materials";
const scene = new Scene(engine, { useGeometryUniqueIdsMap: true });
scene.debugLayer.show();
let gridMaterial = new GridMaterial("grid", scene);
Which results in the error:
- error ./node_modules/@babylonjs/gui-editor/dist/babylon.guiEditor.max.js:3:0
Module not found: ESM packages (@babylonjs/core) need to be imported. Use 'import' to reference the package instead. https://nextjs.org/docs/messages/import-esm-externals
https://nextjs.org/docs/messages/module-not-found
Import trace for requested module:
./node_modules/@babylonjs/inspector/dist/babylon.inspector.bundle.max.js
./src/visualizer/scene.ts
./src/components/VisualizerCanvas/VisualizerCanvas.tsx
- warn Fast Refresh had to perform a full reload due to a runtime error
So, the reason is the way the modules are being parsed (probably by webpack, but I didn’t dig too much). The inspector depends on gui-editor, which is relatively optionaly if you don’t use GUI, but we can’t detect it when compiling. The problem is that the package is still using require (and not directly import), which is “UMD”-ish. Next didn’t like it at ALL, because it is an external dependency. If you would use it in your project directly (like you do the inspector) it would parse it correctly.
The solution is async-loading (which I would recommend anyhow, since the inspector will influence your package size, and is usually not needed in production). Instead of calling
scene.debugLayer.show();
Remove all references to the inspector and debug layer, and add this instead:
Thanks for your time! Obviously, it worked for you somehow, but I cannot get it to run. Where did you put your code snippet?
I removed the references and imports on top, the direct .show call and replaced them with the Promises.all(). Sadly my error is not gone yet. Just to confirm my understanding: your fix would just be to load the imports ‘manually’ in the function itself, put it in a promise.all which waits for each promise to resolve and then use the previous scene to show the debug.layer?
So we are basically just manoeuvring around the next compiler and it’s hard warning about external libraries?
In short: this change, still produces the same error for me:
the demo worked for a brief time. I saw my scene and the inspector. I’m not sure what happened then. On the next start or after a hotreload the whole setup crashed again and could not be started again.
Thanks again for your time and effort! I cloned your pr, changed nothing and started it with yarn dev. The scene starts and I see the Babylon inspector, but the ground and sphere are lost, due to another importing issue. I tried already to import the StandardMaterial manually but it did not change anything. So sadly I could not ‘reproduce’ a working setup on my end yet, even with directly cloning your fork and branch.
You need to import the standard material to get it to work.
Until now you were loading everything from @babylonjs/core (the base directory) which prevented tree shaking from working correctly. My PR was just showing you how you can do that a little better (and get the inspector working as well). The missing line is