extends-mixin v1.3.0
extends-mixin
The purpose of this package is to provide a function for reducing a collection of mixins into a single mixin that applies each of the mixins. Let's take an example:
Lets assume we have a Person
class with a name
field that we want to augment
to include accessors for accessing a person's first and last name.
class Person {
constructor(name) {
this.name = name;
}
}
const john = new Person('John Doe');
assert.equal(john.name, 'John Doe');
We can create a mixin to get the first name like so:
const canGetFirstName = Base => class extends Base {
get first() {
return this.name.split(' ').shift();
}
};
const PersonWithFirstName = canGetFirstName(Person);
const john = new PersonWithFirstName('John Doe');
assert.equal(john.name, 'John Doe');
assert.equal(john.first, 'John');
We can also create another mixin to get the last name like so:
const canGetLastName = Base => class extends Base {
get last() {
return this.name.split(' ').pop();
}
};
const PersonWithLastName = canGetLastName(Person);
const john = new PersonWithLastName('John Doe');
assert.equal(john.name, 'John Doe');
assert.equal(john.last, 'Doe');
If we want to combine the mixins, we would typically do something like this:
const PersonWithFirstAndLastName = canGetFirstName(canGetLastName(Person));
const john = new PersonWithFirstAndLastName('John Doe');
assert.equal(john.name, 'John Doe');
assert.equal(john.first, 'John');
assert.equal(john.last, 'Doe');
While this appears ok for two mixins, it becomes difficult to read as the number of mixins increase. Consider the following:
const CustomPerson = canGetFirstName(canGetLastName(canGetChildren(canGetSiblings(Person))));
The purpose of this package is to make combining mixins easier by allowing you to do this:
const mix = require('extends-mixin');
const canGetAncestry = mix([
canGetFirstName,
canGetLastName,
canGetChildren,
canGetSiblings
]);
const CustomPerson = canGetAncestry(Person);
You can also pass each mixin as an argument if it is more convenient:
const mix = require('extends-mixin');
const canGetAncestry = mix(
canGetFirstName,
canGetLastName,
canGetChildren,
canGetSiblings
);
const CustomPerson = canGetAncestry(Person);
If your mixin list happens to be empty, the identity function is returned:
const mix = require('extends-mixin');
const identity = mix();
const JustAPerson = identity(Person);
const john = new JustAPerson('John Doe');
assert.equal(john.name, 'John Doe');
Because this package reduces many mixins to a single mixin, grouping mixins is easy:
const mix = require('extends-mixin');
const canGetFirstAndLastName = mix(canGetFirstName, canGetLastName);
const canGetChildrenAndSiblings = mix(canGetChildren, canGetSiblings);
const canGetAncestry = mix(canGetFirstAndLastName, canGetChildrenAndSiblings);
const CustomPerson = canGetAncestry(Person);
As a convenience, a function is provided for loading all mixins within a
directory. Nested directories are required as normal. Only files with .js
extensions are accepted and index.js
is ignored. A typical index.js
would be the following:
module.exports = require('extends-mixin/all')(__dirname);
Pull requests and bug reports are welcome, as always.