Publishing the Babylon.js Tree

Given the opportunities for tree shaking BJS modules would it be possible to auto generate and publish the tree in a way to see what modules might be needed for a particular project?

Even better; say I needed an arc rotate camera, a directional light, to be able to create a box with standard material and import a model from a .glb file with non-skeleton animation could it be possible to tick boxes and a list of modules needed produced?

Better still print a list of the modules formatted depending on the form needed, ie <script>, or import or for using the @ notation etc?

1 Like

@RaananW is working on an amazing improvment where all this will be in the past :slight_smile:

6 Likes

The idea behind tree shaking is keeping only what you need. In a perfect tree-shaken world, you will only have the modules you need, while automagically throwing away everything you don’t use.
This works partially when using the es6 packages. When building your project, depends on the builder) you can export the list of used imports and see the entire dependency tree.
For webpack you have this - webpack-bundle-analyzer - npm
For rollup - GitHub - btd/rollup-plugin-visualizer: 📈⚖️ Visuallize your bundle

Oh, and… Yes, I am working on a better esm support so that tree shaking will be work as expected :slight_smile: Stay tuned.

6 Likes

You can run postinstall scripts to do what youre describing, sometimes you may need to be a little creative. I prefer to just set my tsconfig baseUrl to src and put stuff under src/babylonjs, but install @babylon/core from npm. For ex, I got evgeni’s ocean shader demo down to 600kb i think it was. There are a few ways to check all your projects imports. You can simply concat and all your source files, sort the imports, and copy/paste all the import declarations. You can also do regex tests or use babel or typescript to check the ast. The effort is rarely worth it though tbh. Another way is to install babylon from git instead of npm. The code on npm is es5 , still esm, but transpiled down to es5 plus some typescript junk , both of which make things harder to identify used code paths. To build using the github source code, you’ll have to use a string plugin and add the shader extensions

What you suggest is great for experienced developers. I am a hobbiest that likes playing with code but not with all the faff of setting up the correct build environment and compiling. Thus I love the immediacy of Javascript and use typescript only when necessary. I may be wrong but I believe there could be a lot of beginners, users and potential users that think along the same lines as me. You could say “well in that case load babylonjs and work with that.”. However it is not much more to the next step of building a small project and hosting it externally for others to use. In which case minimizing overall file size would be something you would want. You could then say “learn a proper build environment and how to use it first.” but perhaps that is a step too far for some users and I see the potential in a case where a user, without studying the list of babylon.js modules,knows from the tutorial docs what is available and indicates what they need at a very top level and are then presented with a list of modules to import.

From what @RaananW said above, and I might be too optomistic, that at some point the written code could be scanned and the modules needed automagically included.

So my suggestion was for a simple minded approach for simple minded people like myself. :smiley:

1 Like

We know each other a few years now, and one thing I would never call you is simple minded :wink:

Using the UMD version (i.e. - what we have on our CDN) will simply load everything, just like in the playground. I think we might be defining “modules” differently, but I am not sure. For me a module (in the sense of ES-Modules) is practically any element being exported by Babylon.js that can be imported in your code. Using the future esm babylon package will work just like the CDN’s version if you don’t “filter” it using a build system. The browsers support loading ESM files, just like they support loading UMD.

the definition of “module” is definitely a problem. In webpack, and in node, a module is a file. As in , module.exports also has a property module.id, which is just the filename. In ESM, the definition is a little blurry. I remember seeing anders heljsberg complain about how they defined some syntax but gave no guidance on implementation. I also always get confused about what defines a module, the importer or the exporter, like the chicken before the egg problem. The answer is that using the export keyword defines the file as module. So, in esm, a module is still a file, not the actual imported identifiers. Small background info, you’ll also see the words specifiers and identifers used when people talk about things using their big brains, identifiers are just js objects and identifers are uri strings. Helpful to know when you’re looking for language related packages or ast tools.
.JavaScript modules - JavaScript | MDN
MDN says “…place [export] in front of any items you want exported out of the module”. So, MDN is defining a module as a file also, not the individual exports. But, like Raanan said “For me a module (in the sense of ES-Modules) is practically any element being exported…” , I totally use and think of the term module like that also, but its actually wrong. It’s infuriating lol.

The whole esm thing has real world consequences too. You may not know this, but when you use proper esm imports, the imported objects become shared across v8 context just like builtin objects, such as Array or Map. That is huge right? It means you can just spam iframes to your BENEFIT now, because chromium will put the child frame in another thread, while sharing the modules across memory. V8 also has a concept virtual threads, that it uses to kind of glue together multithreading and the security model, and using the stupid esm syntax or adding type=“module” to a script plays an enormous role in memory performance. I did some test in a nextjs app where I added a button that spammed a hello world div inside an iframe - so just a simple page that could add a bunch of iframes to a list. If you naively imported this module through next/webpack, spamming 20 of them would increase memory ~ 200mb . If you put it in the public folder and avoided webpack and maintained compliant esm syntax, adding those same 20 iframes only added 1-4mb. All from using 1 or 2 extra keywords.

Hilariously, wasm uses node style naming WebAssembly.Module.exports() - JavaScript | MDN

Also, some people seem to think they’re onto something with esm imports. But, I actually completely disagree. GitHub - google/node-sec-roadmap: Some thoughts on how Node.js might respond to a changing security environment . Spoofing and mitm is how things get done in the real world, using remote urls to import things is, imo, a much larger security risk.