JS Module - Exporting functions

Hi guys !

I know my problematic isn’t linked to THREEJS but I think you’ll be able to answer me ! :slight_smile:

I have an index.html page that includes 2 js files, 1 as “text/javascript” (let’s call it custom.js), 1 as “module” (let’s call it module.js).
How to export functions from module.js to use them on custom.js as long as custom.js can’t use the import functionality as long as it’s not a module ? :confused:

Thanx you in advance !

I guess you can’t. You should use all js files as modules.

1 Like

Correct. The idea of modules is to avoid exactly this anit-pattern (defining entities in global scope or global namespaces).

I see !

But by doing so, it isn’t possible to test using the Chrome Developper Console. It is also impossible to act on a THREEJS Canvas through an HTML Button (OnClick event).

No way to test / interact using HTMLElements with this kind of configuration ?

I actually defined my vars in my custom.js that permit me to interact with them on a global scope. Maybe there is an equivalent for functions, like prototypes in C++ ?

Sorry, but these statements are way too broad and thus not true. Of course you can debug the code with Chrome Dev Tools and of course you can register event listeners from module code.

Then I don’t understand what I am doing wrong. :frowning:

When I try to start a function using the Chrome Developper Console, it says that my function is not defined. My function is declared through my module (called addCube() in that case).

Sure for event listener on modules, I am using them ! But I mean, if I place this on DOM :

<button onClick="addCube();"></button>

It will result in “Uncaught ReferenceError: addCube is not defined”. Note that this button is dynamically added by another function of my module. So yeah, I can transform this to :

  1. Adding the button dynamically.
  2. Add an event listener on the created button that will trigger my function.

This will probably work. But what about the Console ? :confused:

Ah, now I see! Yes, this approach does not work when addCube() is defined in a module. You need something like this then:

<button id="add-cube"></button>
const button = document.getElementById( 'add-cube' );
button.addEventListener( 'click', addCube );

And yes, you can’t invocate the function over the browser console since it is defined in a module (and thus not globally available).

Thanx ! :slight_smile:

But as previously said, no way to make functions available in global scope using some kind of “prototype” ? Maybe a anonymous function englobing another function from the module ?

Here’s what I tried :

// From custom.js
var THREE, LineGeometry, LineMaterial, Line2;

And then :

// Import THREEJS - From Module.
import * as THREEPrototype from './three.module.js';
import * as LineGeometryPrototype from '../lines/LineGeometry.js';
import * as LineMaterialPrototype from '../lines/LineMaterial.js';
import * as Line2Prototype from '../lines/Line2.js';


$(document).ready(function() {
	THREE = THREEPrototype;
	LineGeometry = LineGeometryPrototype;
	LineMaterial = LineMaterialPrototype;
	Line2 = Line2Prototype;

Guess what ? It worked ! This way I can access THREE modules vars. What next ? I just have to move my functions from my module to my custom.js. The problem is that I have to do it for every functionnally (scene, camera, plane, etc) ! :frowning:

Anyone have a better solution ? The only other solution I’ve found is to use Esprima to list all var declared in scope and add them to an array of vars to redeclare every “Prototype var” into this array… but it sounds like using a hammer to cruch a gnat…

actually I’m thinking about this just now too. I used to write everything at global scope, and am modernizing my patterns for this project.
I’m not sure the best way though, particularly for what you mentioned - scene, camera, renderer. I’ll initialize them as
window.renderer = new THREE.WebGLRenderer()
but I would be happy to hear if there’s a better way

[edit] - ok I’m now doing what I believe is the correct way -
make an “init” function within the module, which first returns if exists, initializes if not…