Babylon.js: BabylonJS Typescript imports fail for MochaJS specs

While attempting to set up a unit testing environment that involves MochaJS and BabylonJS, the importing of BabylonJS parts threw two types of errors:

  1. SyntaxError: Named export 'Camera' not found.
  2. SyntaxError: Cannot use import statement outside a module. Tests are running with a dedicated tsconfig.json and a .mocharc.js config. This GitHub repo contains a full test and demo setup.

Comparison was made to Typestrong/ts-node-repros example repo.

Key facts:

  1. Node Version: 14.17.0
  2. Mocha: loader: 'ts-node/esm'
  3. package.json: "type": "module"
  4. TS config:
{
	"compilerOptions": {
		"module": "ES2020",
		"target": "ES2020",
		"moduleResolution": "node",
		"esModuleInterop": true
	}
}

Note: All Mocha options can be found here.

Repro

  • Bug repro on playground: As the tests are running in the CLI and as it’s about imports, the issue can not get reproduced in the playground. Please refer to this this GitHub repo for a reproduction: Clone and run either of npm run test-{A|B}.
  • Expected result:
  • Current result: See Console error log below.

Screenshots Console error log

Test case A

$ npm run test-A

> demo/ts-mocha-babylonjs@0.1.0 test-A
> ./node_modules/.bin/mocha --config .mocharc-A.cjs -P ./tsconfig.json

(node:133305) ExperimentalWarning: --experimental-loader is an experimental feature. This feature could change at any time

/path/to/ts-mocha-babylonjs/tests/case-A.spec.ts:13
import { Camera } from '@babylonjs/core/Cameras/camera.js';
         ^^^^^^
SyntaxError: Named export 'Camera' not found. The requested module '@babylonjs/core/Cameras/camera.js' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:

import pkg from '@babylonjs/core/Cameras/camera.js';
const { Camera } = pkg;

    at ModuleJob._instantiate (internal/modules/esm/module_job.js:97:21)
    at ModuleJob.run (internal/modules/esm/module_job.js:142:20)
    at Loader.import (internal/modules/esm/loader.js:182:24)
    at formattedImport (/path/to/projects/ts-mocha-babylonjs/node_modules/mocha/lib/esm-utils.js:7:14)
    at Object.exports.loadFilesAsync (/path/to/projects/ts-mocha-babylonjs/node_modules/mocha/lib/esm-utils.js:55:20)
    at singleRun (/path/to/projects/ts-mocha-babylonjs/node_modules/mocha/lib/cli/run-helpers.js:125:3)
    at Object.exports.handler (/path/to/projects/ts-mocha-babylonjs/node_modules/mocha/lib/cli/run.js:362:5)

Test case B

$ npm run test-B

> demo/ts-mocha-babylonjs@0.1.0 test-B
> ./node_modules/.bin/mocha --config .mocharc-B.cjs -P ./tsconfig.json

(node:133357) ExperimentalWarning: --experimental-loader is an experimental feature. This feature could change at any time
(node:133357) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.

/path/to/projects/ts-mocha-babylonjs/node_modules/@babylonjs/core/Cameras/camera.js:1
import { __decorate, __extends } from "tslib";
^^^^^^

SyntaxError: Cannot use import statement outside a module
    at wrapSafe (internal/modules/cjs/loader.js:915:16)
    at Module._compile (internal/modules/cjs/loader.js:963:27)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
    at Module.load (internal/modules/cjs/loader.js:863:32)
    at Function.Module._load (internal/modules/cjs/loader.js:708:14)
    at ModuleWrap.<anonymous> (internal/modules/esm/translators.js:195:29)
    at ModuleJob.run (internal/modules/esm/module_job.js:145:37)
    at Loader.import (internal/modules/esm/loader.js:182:24)
    at formattedImport (/path/to/projects/ts-mocha-babylonjs/node_modules/mocha/lib/esm-utils.js:7:14)
    at Object.exports.loadFilesAsync (/path/to/projects/ts-mocha-babylonjs/node_modules/mocha/lib/esm-utils.js:55:20)
    at singleRun (/path/to/projects/ts-mocha-babylonjs/node_modules/mocha/lib/cli/run-helpers.js:125:3)
    at Object.exports.handler (/path/to/projects/ts-mocha-babylonjs/node_modules/mocha/lib/cli/run.js:362:5)

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 5
  • Comments: 23 (17 by maintainers)

Most upvoted comments

@franz-josef-kaiser ok so your repro repository doesn’t reproduce the error anymore 😅 (maybe you better have created a new branch for your experimentations?)

Anyway, I fixed my issue by adding a jest.config.js file to my project:

module.exports = {
  transformIgnorePatterns: [
    "/node_modules/(?!(@babylonjs\/core)/)"
  ]
};

Sometimes it happens (especially in React Native or TypeScript projects) that 3rd party modules are published as untranspiled code. Since all files inside node_modules are not transformed by default, Jest will not understand the code in these modules, resulting in syntax errors. To overcome this, you may use transformIgnorePatterns to allow transpiling such modules

See also:

I have exact same problem with TypeScript and Jest 🤔

Note that I’m using Node.js v14.17.6 (and npm v6.14.15)

image

Babylon.js is the only npm package I’m unable to use in my unit tests…

Any news about that? Maybe a workaround?

I’ve also checked the issue on the forum but I prefer GitHub issues for the notification system

Edit: I found the solution --> https://github.com/BabylonJS/Babylon.js/issues/10507#issuecomment-1004885962 👍

Don’t worry. We have core teams member lurking on the forum, they will answer really fast

maybe you better have created a new branch for your experimentations?

Probably. You know, if I knew, you were waiting right around the corner :octocat: …

Thanks for jumping in and updating the issue with your findings!

what os are you on ?

for me it is also all good on 16 image

I wonder if it could be a path matching failing on linux for instance