nikku / didi

Dependency Injection for JavaScript
MIT License
92 stars 17 forks source link

Destructured Function Parameter Injection #14

Open basejump opened 2 years ago

basejump commented 2 years ago

Would be great to support unpacking or destructured objects for function parameters. Working on a PR here with update to the readme.

// destructured object parameter wont require any annotations. 
function createEngine({power}) { ... }

//then in module config can take the simple route as well since function params are parsed and $inject is automatically added
const carModule = {
  engine: ['factory', createEngine ],
  power:  ['value', { horses: 400 }]
};

Let me know what you think. Would this be something your interested in merging in. Plan on finishing tests today and will convert PR off draft once done. Great project, thanks.

basejump commented 2 years ago

PR is updated. Will push more if we discover more issues in out testing. my REGEX kungfu is not so great. I am certain there is a better way to parse the parameters to slim is down a bit than what I did, but its working.

It will add about only about 0.4k to the minified size, and a negligible increase to the gzip size, to enable a very powerful and flexible design pattern. albiet: the RORO design pattern is great but itself adds some weight if size is crucial since the minification process does not mess with the object property names. so the functions parameter destructuring gets kept. Makes it great for injection with DIDI though.

nikku commented 2 years ago

Looks like something that could be worth supporting, especially as it would make generating typings very powerful (TS setup that is):

import { InjectionContext } from '../types';

function Car({ power } : InjectionContext) {
  ...
}

However, whatever we support should work without major caveats, and shall be properly tested. I'd be afraid that it would take quite some regex-ninja to get instantiation right (and I don't want to add a JS ast-parser to this library).

A couple of examples:

// inject `power as foobar`
function Car({ 
  power: foobar
}) { 
  // access `power` as `foobar`
}

// default value for power
function Car({ 
  power = 1000
}) { 
  // if power is not provided, default to 1000
}

// interaction with existing patterns
function Car({ 
  power = 1000
}) { 
  // if power is not provided, default to 1000
}

Car.$inject = [ 'config.car' ];