Correct way to use ES6 modules and import classes

Hi,

I am making a project in p5.js where I have a simple class called Stone that I want to import into another file using ES6 modules. So I used export default :

// js/src/Stone.js

export default class Stone {
    constructor(x, y, is_white) {
        this.x = x;
        this.y = y;
        this.is_white = is_white;
    }
}

And I have a main file called main.js which is included in the HTML as a module like this :

// index.html

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

And I import my previous class :

// js/main.js

import Stone from './src/Stone.js';

Now, the problem is that p5 doesn’t recognize the functions draw() and setup() because they are in a different module not in the global namespace.

I found this video explaining that :

But I wanted to know if there was a better solution to achieve this than doing (and passing a reference of p5 to any of the class functions that uses p5 functions or variables):

new p5(function(p5){
  p5.setup(){
    //...
  }

  p5.draw(){
   //...
  }
});

Any suggestions are welcome ! :slight_smile:

1 Like
1 Like

Thanks a lot @GoToLoop, I should have checked before on the forum :hugs:

I am now able to use p5 global functions in my classes without passing an instance of p5 in the constructor which is great compared to Java :+1:

1 Like

If you want your “p5.js”-depended classes to work for both global & instance mode sketches, you’re gonna need to require the sketch’s p5 reference on their constructor: :construction_worker_man:

export default class Stone {
  constructor(x, y, is_white, p) {
    this.x = x;
    this.y = y;
    this.is_white = is_white;
    this.p = p;
  }
}

But to make global instance user’s lives easier, we can turn the p5 p parameter optional by assigning the “secret” property p5.instance as its default value: :male_detective:

export default class Stone {
  constructor(x, y, is_white, p = p5.instance) {
    this.x = x;
    this.y = y;
    this.is_white = is_white;
    this.p = p;
  }
}

Take a look at class Ball’s construtor() from file “ball.mjs” as an example of it: :eyeglasses:

1 Like

All right thanks for the example.

I noticed that in JavaScript, we must use the keyword this to refer an attribute inside a class that’s why you say (in your example) :

const { p, c } = this;

but it’s not efficient at all isn’t it? It means that at each method call, you are going to create a variable.
In the same time, saying :

this.p.ellipse(...);
this.p.random();
this.p.fill();
// ...

is quite heavy when writing :frowning: