BABYLON namespace seems to be global in typescript

I don’t have a playground reproduction because this problem occurs specifically in vscode/my editor.

The issue I’m having is that the BABYLON namespace seems to be imported/declared globally in typescript (or something? I’m new at typescript).

In particular, if I import any babylonjs export in one file (e.g. import {Engine} from 'babylonjs'), vscode seems to recognize the BABYLON namespace in all other files, where I would expect it not to (i.e. throw an error about not knowing the BABYLON namespace).

So for example, suppose I have a file like babylon.ts containing the code

import {Engine} from 'babylonjs';

const canvas: HTMLCanvasElement = document.createElement('canvas'); 
document.body.appendChild(canvas); 

// Note that this line doesn't work at all, 
// and throws the error "Type 'import("babylonjs/Engines/engine").Engine' is not assignable to type 'BABYLON.Engine'."
engine = new Engine(canvas,true);

and another file, say babylon_objects.ts, that contains just

// Would expect vscode to throw an error like "Cannot find name BABYLON"
const vector = BABYLON.Vector3.Zero(); 

What I would expect is that vscode would be upset about me trying to using the name/namespace BABYLON in babylon_objects.ts without having declared it anywhere, but instead it seems fine with it, lets me compile the code, and then I get an error like the following from the browser (noting that I have to change the line engine = new Engine(canvas,true); to engine = new BABYLON.Engine(canvas,true); to get the code to compile).

babylon.ts:20 Uncaught ReferenceError: BABYLON is not defined
    at new D (babylon.ts:20:27)
    at index.ts:4:25
    at index.ts:10:24

Again, I don’t have a playground to demonstrate this, but I do have the repo with the code, if someone wants to try this for themselves.

Can someone help me understand what’s going on here?

Please let me know what other info that I have not provided would be useful. Thanks.

cc @RaananW, I don’t know if you can import the babylonjs package this way or if you must use the es6 distribution (Babylon.js ES6 support with Tree Shaking | Babylon.js Documentation)…

What I can see is that if you F12 on babylonjs in import { Engine } from 'babylonjs'; you are directed to this code in node_modules/babylonjs/babylon.module.d.ts:

declare module "babylonjs" {
    export * from "babylonjs/Legacy/legacy";
}

and module babylonjs/Legacy/legacy is declared as:

declare module "babylonjs/Legacy/legacy" {
    import * as BABYLON from "babylonjs/index";
    export * from "babylonjs/index";
    export const Debug: {
        AxesViewer: typeof BABYLON.AxesViewer;
        BoneAxesViewer: typeof BABYLON.BoneAxesViewer;
        PhysicsViewer: typeof BABYLON.PhysicsViewer;
        SkeletonViewer: typeof BABYLON.SkeletonViewer;
    };
}

which would explain why the BABYLON namespace is visible.

1 Like

Right I think that makes sense. Do you have any suggestions?

Can I ask if you need the BABYLON namespace, or would importing everything you need work better for your usecase?

As @Evgeni_Popov said - the es6 packages would be a much better option if you don’t need to use the global namespace. replacing babylonjs with @babylonjs/core would benefit your project for sure

2 Likes

I don’t think I strictly need the BABYLON namespace, and I encountered this issue as a result of trying to import just what I need, rather than all of babylonjs.

Is switching to the es6 packages a matter of setting that in tsconfig.json?

Also replacing babylonjs with @babylonjs/core doesn’t seem to work, typescript can’t find the @babylonjs/core module.

You should, of course, add the package in your package.json as a dependency. The guide’s link was pasted here before:

Sorry, I saw that link, but wasn’t sure what to make of it. Still learning. Can you tell me the difference between adding a dependency as a dev dependency vs. not? Is that where the problem is coming from?

no, it is not. if your project is not being published on npm there is little difference between the two. At least no serious difference for your local project.

Looks like Havok is missing from the packages list, is that list out of date?

havok’s package is @babylonjs/havok, but it is not dependent on core, and is in a different repository so it is documented at a different place: