npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

mixwith

v0.1.1

Published

A simple, powerful mixin applier for JavaScript classes

Downloads

333,483

Readme

mixwith.js

A simple, powerful and safe mixin library for ES6.

Overview

mixwith differs from other mixin approaches because it does not copy properties from one object to another. Instead, mixwith works with "subclass factories" which create a new class that extends a superclass with the mixin - this is called a mixin application.

Subclass factory style mixins take advantage of two awesome features of ES6 classes: class expressions, and expressions in the extends clause of a class declaration.

Quick Example

Define a Mixin:

let MyMixin = (superclass) => class extends superclass {
  // mixin methods here
};

Use a Mixin without mixwith:

class MyClass extends MyMixin(MySuperClass) {
  // class methods here, go ahead, use super!
}

Use a Mixin with mixwith:

class MyClass extends mix(MySuperClass).with(MyMixin, OtherMixin) {
  // class methods here, go ahead, use super!
}

mixwith preserves the object-oriented inheritance properties that classes provide, like method overriding and super calls, while letting you compose classes out of mixins without being constrained to a single inheritance hierarchy, and without monkey-patching or copying.

Advantages of subclass factories over typical JavaScript mixins

Method overriding that just works

Methods in subclasses can naturally override methods in the mixin or superclass, and mixins override methods in the superclass. This means that precedence is preserved - the order is: subclass -> mixin__1 -> ... -> mixin__N -> superclass.

super works

Subclasses and mixins can use super normally, as defined in standard Javascript, and without needing the mixin library to do special chaining of functions.

Mixins can have constructors

Since super() works, mixins can define constructors. Combined with ES6 rest arguments and the spread operator, mixins can have generic constructors that work with any super constructor by passing along all arguments.

Prototypes and instances are not mutated

Typical JavaScript mixins usually used to either mutate each instance as created, which can be bad for performance and maintainability, or modify a prototype, which means every object inheriting from that prototype gets the mixin. Subclass factories don't mutate objects, they define new classes to subclass, leaving the original superclass intact.

Usage

Defining Mixins

A mixin is simply a function that takes a superclass and returns a subclass of it, using ES6 class expressions:

let MyMixin = (superclass) => class extends superclass {

  constructor(args...) {
    // mixins should either 1) not define a constructor, 2) require a specific
    // constructor signature, or 3) pass along all arguments.
    super(...args);
  }

  foo() {
    console.log('foo from MyMixin');
    // this will call superclass.foo()
    super.foo();
  }

};

Mixins defined this way do not require any helpers to define or use. You can use this pattern without mixwith at all!

Using Mixins

Without mixwith, just invoke them inside a classes extends clause:

class MyClass extends MyMixin(MySuperClass) {
}

mixwith provides a helper that's a bit nicer when applying multiple mixins, and adds some features like mixin-deduplication and @@hasInstance support (@@hasInstance overloads instanceof, but isn't supported in any browsers yet).

class MyClass extends mix(MySuperClass).with(MyMixin) {
}

Classes that use mixins can define and override constructors and methods as usual.

class MyClass extends mix(MySuperClass).with(MyMixin) {

  constructor(a, b) {
    super(a, b); // calls MyMixin(a, b)
  }

  foo() {
    console.log('foo from MyClass');
    super.foo(); // calls MyMixin.foo()
  }

}