BabylonJs with React - Problem with custom scene

Hi everyone,

I’m trying to build a ReactJs app in which I would load a local .babylon scene.

I have followed this documentation about ReactJs and BabylonJs : How to use Babylon.js with ReactJS - Babylon.js Documentation

And I kept the first component which load the canvas.

I have changed the function ‘onSceneMount’ of the 2nd component ‘PageWithScene’ to load my custom .babylon scene as below :

onSceneMount = () =>{

	SceneLoader.Load("/scene/Salon/", "scene.babylon", this.engine, (scene) => {

		this.scene = scene;
  
		// No camera?
		if (!this.scene.activeCamera) {
		  this.scene.createDefaultCamera(false, true, true);
		}
  
		// Attach camera
		this.scene.activeCamera.attachControl(this.canvas, true);
  
		// Load extensions
		Tools.LoadFile("/scene/Salon/project.editorproject", (data) => {
		  // Apply extensions (such as custom code, custom materials etc.)
		  Extensions.RoolUrl = "/scene/Salon/";
		  Extensions.ApplyExtensions(this.scene, JSON.parse(data));
  
		});

		this.engine.runRenderLoop(() => {
			this.scene.render();
			});
	})
}

The problem i’m actually dealing with since couple of day is ‘TypeError: fs.existsSync is not a function’.
A solution i find on different forum is to set ‘window.require = fs(path)’ insteed of ‘require = fs(path)’ but that’s leading me to another error : 'window.require is not a function".

I am short of solution actually, I may have gone in the wrong direction about the functions onSceneMount() or SceneLoader.Load()

Thank you !

Not knowing the environment you are trying to deploy this on (seems like a browser :slight_smile: ), I am not sure what component is trying to use the fs module (which is the file-system module of node JS.

Care to share a bit more information about the app and what you are developing? Electron? Want to share a full stacktrace so we can help further?

Hello ! Sorry, i’m was busy those days !

I’m trying to deploy this environment on a Browser !

Component is trying to use the fs module is this one :

import * as BABYLON from ‘babylonjs’;
import React from ‘react’;
import ‘babylonjs-loaders’;
import ‘…/App.css’;

export default class Scene extends React.Component {

scene;
engine;
canvas;

onResizeWindow = () => {
if (this.engine) {
this.engine.resize();
}
}

componentDidMount () {
this.engine = new BABYLON.Engine(
this.canvas,
true,
this.props.engineOptions,
this.props.adaptToDeviceRatio
);

let scene = new BABYLON.Scene(this.engine);
this.scene = scene;


if (typeof this.props.onSceneMount === 'function') {
  this.props.onSceneMount({
    scene,
    engine: this.engine,
    canvas: this.canvas
  });
} else {
  console.error('onSceneMount function not available');
}

// Resize the babylon engine when the window is resized
window.addEventListener('resize', this.onResizeWindow);

}

componentWillUnmount () {
window.removeEventListener(‘resize’, this.onResizeWindow);
}

onCanvasLoaded = © => {
if (c !== null) {
this.canvas = c;
}
}

render () {
let { width, height} = this.props;

let opts = {};

if (width !== undefined && height !== undefined) {
  opts.width = width;
  opts.height = height;
}

return (
  <canvas
    className="canvas"
    {...opts}
    ref={this.onCanvasLoaded}
  />
)

}
}

And I don’t want to use an Electron scene, is it possible ?

Pinging @sebavan

Could you try replacing import * as BABYLON by import * as bab for instance, basically anything else than BABYLON or you will conflict with the namespace.

1 Like