This is a perfect example why “Composition over Inheritance” is a good practice.
As stated before, you should write wrappers around the THREE.js objects. Let THREE.js become “an internal” in your engine, not something that ‘blends in’, otherwise you’ll always have issues like these when updating to a newer version.
I’ve always went with the approach of not touching or modifying the original code, but rather write wrappers around the objects. Yes, you’ll create some boilerplate code (basically quite a few proxy methods), but at least it won’t break the internal API’s of your own engine. When updating THREE, you’ll only have to fix the points in your own code which directly use THREE’s own objects.
For example:
# Your Mesh class which extends THREE.Mesh
export class MyMesh extends Mesh
{
// Your own code.
}
# Some random part in your own code:
const m = new MyMesh();
m.position.set(x, y, z); // <- This is actually a call to THREE.Mesh.position.set
If for whatever reason, THREE decides to change the method signature of set
, you’ll have to update every part of your own code where set
is being called.
Now, taking the “Composition over Inheritance” approach:
# MyMesh wraps THREE.Mesh
export class MyMesh
{
private _mesh: Mesh = new Mesh();
public setPosition(x: number, y: number, z: number): MyMesh
{
this._mesh.position.set(x, y, z);
return this;
}
}
Now, if THREE decides to change the method signature of the set
method, you’ll only need to update the setPosition
method in your own code.
This is just a hypothetical example of course, but hopefully it shows how easily maintainable your own code becomes when a new update of THREE is released which you want to use.