pluginjector

1.0.7 • Public • Published

pluginjector

Simple no nonsense dependency injection for extensibility and testability


Install from NPM

Help with development on GitHub


Donations accepted. 😃 😃 😃 $5 paypal $5 😘 😘 😘

- Usage -

Note: Uses ES6/ES2015 features and may fail on Node versions prior to v6.

Pass your core module object to pluginjector then inject plugins
 
const pluginjector = require('pluginjector')
 
const inject = pluginjector(myModule)
 
const myNewModule = inject(myPlugin)
 
Overwrite properties in your module
 
const myModule = { val: 1 }
const myPlugin = { val: 2 }
 
const newModule = pluginjector(MyModule)(myPlugin)
 
assert(newModule.val === 2) // true
 
Overwrite methods in your module
const myModule = {
  method (){return 'method'}
}
 
const myPlugin = {
  method (){return ('plugin')}
}
 
const newModule = pluginjector(MyModule)(myPlugin)
 
assert(newModule.method() === 'plugin') // true
 
Namespace your plugins
 
const myPlugin {
  method( return 'method) 
}
 
const myNewModule = inject({pluginname: myPlugin})
 
assert(myNewModule.myPlugin.method() === 'method') // true
 
Bind this to your methods with a simple flag

more detailed look at this later

 
const myModule = {val: 1}
 
const myPlugin = {
  pluginjectorBindThis: true,
  method (){ return this.val }
}
 
const newModule = pluginjector(myModule)({myPlugin})
 
assert(newModule.myPlugin.method() === 1) // true
 
Pass in files to be imported
 
const newModule = inject('../path/to/my/file')
 
const newNamespacedModule = inject({pluginName: '../path/to/my/file'})
 
// filenames are automatically namespaced in camelCase
 
const nModule = inject('../location/my-plugin')
assert( !!nModule.myPlugin ) // true
 
Include a default directory and your users can pass in just the plugin name.
 
const inject = (myModule, {dir: '../path/to/default/directory'})
 
const newModule = inject('pluginName')
 
const newNamespacedModule = inject({differentPluginName: 'pluginName'})
 
Lazily inject different plugins as needed
 
const inject = pluginjector(myModule)
const newModule = inject({data: 'abc'})
inject({moreData: 'def'})
 
assert(newModule.data + newModule.moreData === 'abcdef') // true
 
Original core is shallow copied to minimize possibility of undesired mutations
 
let inject = plugininjector({data: 'core module'})
const newModule = inject({data: 'new module'})
 
inject = pluginjector(myModule)
const anotherNewModule = inject({})
 
assert(newModule.data === 'new module') // true
assert(anotherNewModule.data === 'core module') // true
 
Optionally use core module as prototype instead of shallow copy
 
const inject = pluginjectore(coreModule, {proto: true})
const newModule = inject(plugin)
 
assert(coreModule.isPrototypeOf(newModule)) // true
 

More detail to understand handling of this binding
const myModule = { val: 1 }
 
const myPlugin = {
  // `this` will naturally point to parent module for first layer
  //    of methods unless you namespace it
  method(){ return this.val }
  obj1: {
    // all methods here will get `this` bound to parent module
    pluginjectorBindThis: true, // flag, any truthy value
    method(){ return this.val },
    method2(){ return this.obj2.val }
  },
  obj2: {
    // no flag, so these will not get special binding
    val:2,
    method: ()=>{ return this.val }
  },
  obj3: {
    // falsey flag doesn't count
    pluginjectorBindThis: false,
    val:3,
    method: ()=>{ return this.val }
  }
}
 
let newModule = require('pluginjector')(myModule)(myPlugin)
 
assert(newModule.method() === 1) // true
assert(newModule.obj1.method() === 1) // true
assert(newModule.obj1.method2() === 2) // true
assert(newModule.obj2.method() === 2) // true
assert(newModule.obj3.method() === 3) // true
 
// with namespace,but no flag, `this` points to `newModule.plugin`
newModule = require('pluginjector')(myModule)({plugin: myPlugin})
assert(newModule.plugin.method() === 1) // false, `this.val` does not exist
 

Package Sidebar

Install

npm i pluginjector

Weekly Downloads

1

Version

1.0.7

License

MIT

Last publish

Collaborators

  • skylize