Calling other from main module

Hello Folks,

I am sure most of you would have encountered this and there is an excellent workaround for this,

my main js file , is getting extremely long ,
is there a way like in other languages where you write the main in one and call this module in all other js files, i understand that is what we do with module calls, would like to know how i would execute this for this particular option,

example on what i am on about ,

can i create a .js file with all the camera settings , and call camera settings in the GLTF importer , and so on…
like,
main camera , scene and lights setup

import * as THREE from './build/three.module.js';

var scene, camera, renderer, directionalLight, canvas;

scene = new THREE.Scene();
const fov = 75;
const aspect = 2;  // the canvas default
const near = 1;
const far = 1000000;

camera = new THREE.PerspectiveCamera(fov,window.innerWidth/window.innerHeight,near,far);
camera.position.set(0, 0, 5);

//canvas = document.querySelector('#canvasId');
renderer = new THREE.WebGLRenderer({antialias:true});
renderer.setSize(window.innerWidth, window.innerHeight);

//setup Lights

directionalLight = new THREE.DirectionalLight(0xff8c19,1.5);
directionalLight.position.set(0,0,4);
scene.add(directionalLight);

document.body.appendChild(renderer.domElement);

say this is called cameraSetup.js
and in the gltfScene.js file can i call this some how ?

or if i call this first

<script type = "module" src="cameraSetup.js"></script>

and next call

<script type = "module" src="gltfScene.js "></script>

this did not work , so any help would save a lot of time going through pages of code

gltfScene.js


import { GLTFLoader } from 'https://threejsfundamentals.org/threejs/resources/threejs/r125/examples/jsm/loaders/GLTFLoader.js';
function initGLTF() {

	time = new THREE.Clock();
	speed = 2; //units a second
	delta = 0;

	raycaster = new THREE.Raycaster();
	
	mouse = new THREE.Vector2();

	rotateReset = new THREE.Matrix4();

	LogotextureLoader = new THREE.TextureLoader();
	Logomap = LogotextureLoader.load('images/weblogWebPage.png');
	Logomaterial = new THREE.MeshPhongMaterial({ map: Logomap });

	const gltfLoader = new GLTFLoader();

	//GLtfSelection = new THREE.Object3D();

	gltfLoader.load('models/testObj.glb', function(gltf) {

		root = gltf.scene;	
		scene.add(root);
		modelFemale = root.getObjectByName('geo');
		
		//console.log(modelFemale);
        
	});
	
	document.addEventListener( 'mousemove', onDocumentMouseMove, false );

}

thanks a lot for the excellent support forum

I think you can if you create a class that you export as a module, if you open up any of the js files in examples/jsm folder you can see how it’s done and pretty much replicate that I think

1 Like

Thanks, i had a look at this and would be great if someone could make an example of the above code , so that i can understand it a bit more

Thanks

you don’t import code that has already run, you import re-usable functions, objects and classes:

cam.js

import * as THREE from 'three'

export class Camera extends THREE.Camera {
  constructor(args) {
    super(args)
    ...
  }
}

app.js

import { Camera } from './cam'

const myCamera = new Camera(args)

modules can have persistent state and there can be valid reasons for that. most often you’d use a state manager that notifies changes. but since this is all vanilla js it’s a bit wild west. personally, i would suggest you don’t dump state into a module and start mutating/reading it from outside, that would work, but it will tank your app in scale.

other than that browser esm is an unproven spec, you make make it extremely hard, or even impossible to create something real. you can’t even use dependencies with that setup. use a bundler, something like vite, which sets up a valid system in seconds. it uses plain esm, but in a sane way.

Thanks for this,

can i get the basics on how to use a bundler ,
on how to, from scratch would be much appreciated ,

if this is straight forward and avoids a lot of problems