BabylonJS development using TypeScript and NOT using Webpack

I’ve been trying to develop a dev environment that lets me use TypeScript + ExpressJS rather than Webpack + Webpack server. I can build the server-side fine compiling to es6, but am stumped how to compile the browser code so that imports pull in the babylon libraries with correct typing.

  1. If you use something like:

import { Scene } from ‘@babylonjs/core/scene’;

It works fine for the typescript compile, but the resulting JS can’t load the libraries in the browser. I
In all cases, the result is:

Uncaught TypeError: Failed to resolve module specifier “@babylonjs/core/”. Relative references must start with either “/”, “./”, or “…/”.

I’ve tried adjusting vales in tsconfig.json in several ways, here is one example:

tsconfig.json

“target”: “es2017”,
“module”: “esnext”,
“moduleResolution”: “node”,

But it doesn’t work.

And, in TypeScript, you can’t specify an import using the .js,

import { Scene } from ‘@babylonjs/core/scene/index.js’;

You could use pure JS like:

BABYLON = require("./vendor/babylon.min.js")

…but then you lose the TypeScript typing, which is the whole point of TypeScript. You can write

let s = new BABYLON.Scene()

but TypeScript won’t know what type ‘Scene’ is, because it was dynamically loaded. You lose the ability to declare

private _scene:Scene;

in your classes.

Does anyone have a (non-Webpack) strategy for getting JS using node_module imports to work in the browser? Some funky tsconfig.json values? Thanks!

Maybe @sebavan or @RaananW will have some clues.

so you could do it only with a special server as it is what we do in our dev tools. Basically appending the missing .js and searching folders for the right files. Then you could use javascript modules to load the files.

The easiest in your case would be to use our babylonjs package (the umd one) not the es6 version. then you could in your ts project use typings and such and your transpiled version would work. It is actually how the playground is working.

OK, just to make sure I understand:

  1. Load umd files like these individually in the browser:

    https://preview.babylonjs.com/materialsLibrary/babylonjs.materials.min.js

  2. Include typings in the project.

Make sense…the part I don’t understand is how to include the typings in the project, since I just started using typescript. Up until now all I’ve been dong is adding @types/xxx in package.json.

So, how do I include those types, is there an example? The tsconfig documentation on the web is pretty confusing. Something like this?

"typeRoots": [
    "./node_modules/@xxx",
],
"types": [
    "babylon",
]

I can see that @babylonjs has .d.ts files in many places, but not sure how to include this information in the project. Thanks!

You can put in one of your ts file this I guess ?

/// <reference path="https://preview.babylonjs.com/babylonjs.d.ts"/>
/// <reference path="https://preview.babylonjs.com/loaders/babylonjs.loaders.d.ts"/>

OK, that almost works! I added the following reference path to the top of the files:

///

And set the ts compiler to:
“target”: “es5”,
“module”: “esnext”,
“moduleResolution”: “node”,

When I do this:

new BABYLON.Engine(…) works…

…but BABYLON.Scene does not work, fails in the browser with:
babylon.js:16 Uncaught TypeError: Cannot read property ‘trackUbosInFrame’ of undefined
at new e (babylon.js:16)
at t._createUbo (babylon.js:16)
at new t (babylon.js:16)
at new PlutonianXR (plutonian.ts:55)

setting target: to es6 gives the same result, BABYLON.Engine ok, Scene not.

OK, just had a bad canvas ID. It looks like it works now, thanks! Also. my TS compiler is running faster. Fixed!

While BabylonJS is great (I have the non-TypeScript prototype for the TS project up at http://plutonianxr.herokuapp.com), the state of JS modules is pretty disappointing…I really thought in 2020 we would be able to write in es2015, use import, and have some option for strong JS typing built into the browser without all these transpiles (sigh). Caniuse shows that only a few edge browers don’t support ES6 (e.g. opera mini).

I have to say I agree, with a huge BUT :slight_smile:

The “but” in that case is - it takes time to fully support that and make sure it works correctly cross browser, and that it requires work on our side that will be taken from developing other features. We have that under our radar, we are planning on revamping the build system and the modules generation. When? That’s a harder question to answer. “As soon as we can” might mean 3 days and might mean 10 months :slight_smile:

Oh, and we still fully support IE11! we are these kind of people. It is dead, it is slow, it is a horrible tool to debug with, but we support it :slight_smile: .

I wasn’t really thinking of Babylon here - the fault is in JS development itself. Everything converged on ES5 about 15 years ago, so JS development wasn’t a big deal. Since then we have a mess - meaning we can’t just write a mix of ES5 and ES6 in popular browsers and have it work. Otherwise, we’d all be writing ES6 directly, old-school!

As far as IE, when I teach frontside JS development, I always require support IE 11 - a good way to learn about browser testing and polyfills! Up until 2014 I used to require IE6 support (first browser with decent CSS).

2 Likes