Error importing BABYLON in multiple modules

Hello,

I was trying to make Babylon work when imported in several modules instead of 1.

What I did is that I build an es6 module for all following parts of BABYLON : “FreeCamera”,“Engine”, “HemisphericLight”, “Vector3”, “CreateSphere”, “Scene”, “NodeMaterial”, and then imported all of them in my page and pasted the following code example : Babylon.js ES6 support with Tree Shaking | Babylon.js Documentation

No matter what material I’m trying to use, I always get the same error : FileTools needs to be imported before [...]

First problem is that fileTools is marked as deprecated, so I don’t know if I should import it or not ?

Second problem is that I don’t know how to import it. If I simply import it in another module, error is still there. Is there anything I should call before ? I was thinking about _injectLTSFileTools maybe ?

Third question : is it even possible to import BABYLON in several modules loaded by browser only when needed like I’m trying to do ? I think so, but I may have problems with my webpack tree-shaking because I only have 3.4kB of modules transferred to my page which seems pretty low, so I may miss many more things.

Probably this template may help you to make things work out of the box - GitHub - RaananW/babylonjs-webpack-es6: Babylon.js basic scene with typescript, webpack, es6 modules, editorconfig, eslint, hot loading and more. Will even make coffee if you ask nicely.

1 Like

Yes it helps a bit thanks. At least to see the structure of the @babylonjs repo.

What I was more looking for was some way to import some parts of @babylonjs dynamically at run time if needed. But the code doesn’t seems to be written for such a thing currently, at least for the big components.

I had to include FileTools in the Engine module to make things work.

Now I’ve some more problem with src/Shaders that are not included. I thought I could specify the path to those .fx, but I can’t even find those files on my computer. I have no idea where do they come from ?

I believe they come from fresnelShader - babylonjs-webpack-es6/src/scenes/fresnelShader.ts at master · RaananW/babylonjs-webpack-es6 · GitHub ?

1 Like

They come from there : @babylonjs/core/Shaders/

I had to include import { helperFunctions } from "@babylonjs/core/Shaders/ShadersInclude/helperFunctions"; in the Engine module to remove this error and be able to use the NodeMaterial.

Now everything is working, I have all my 7 modules loaded at the same time for a total of less than a Mo. Good thing is that I can at run time remove or add some more modules if needed.

Bad things is that it may require some modifications of the Engine module if for example I need to support the import of more Materials… Also, some variable seems to be declare several times so I may load more data compare to if I was using a single module.
But this is quite promising.

cc @RaananW

would be great if you shared the project so I can understand what’s going on :slight_smile:

This is usually a case of a missing import that causes some issues with the way the shaders are included

Ok, I’ll try to post a simple example when I’ll have time. Let me draw you the picture :

I’m currently testing BABYLON in a bigger project that helps loads JS modules at run time when required (by using browser import() or home made polyfill for older browsers).

As the all in one BABYLON is a bit big (4MB), I wanted to split it in elementary modules, and see if those modules loaded independently could still work normally.

So I create 7 JS modules like so : import {Engine} from xyz; export{Engine} , and in another module :
import {Scene} from xyz; export{Scene}, … to import all required BABYLON modules.
After that I imported all 7 modules in the browser, and tried to recreate the example scene.
In the end I managed to make it work, only by adding :
import { helperFunctions } from "@babylonjs/core/Shaders/ShadersInclude/helperFunctions" and
import { FileTools } from "@babylonjs/core/Misc/fileTools"; //seems required
in the Engine module.

It only works with a simple node material though, and I’ll need to add other things to make it work with them. As you said, because I’m only including “Engine” in this module, it’s not capable of telling what shaders needs to be included or not.

What would be great, is if Engine was able to load the required shaders snippets at run time by setting a custom library path to the shaders.js repository (if not already included at compile time).

Of course my solution is a bit weird, and probably nobody else uses it the same way as I do, but I’m pretty happy with the current solution. With my seven modules, total weight (gzipped) is only 658kB, versus 247kB if I build the same scene in a single module, so in the end there is not that much code duplicate.