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

easy-di

v4.0.1

Published

Simple DI module for anything javascript

Downloads

9

Readme

Easy Dependency Injector

Build Status

Simple dependency injection module written in vanilla js.

Why?

There's atleast a thousand implementations of a dependency injection module. Why another?

Honestly, most of them were too heavy for my taste, and didn't provide some of the quirks I'd wanted.

Motivation

Most dependency injection libraries/frameworks have multiple ways of doing the same exact thing. Take angularjs for example. It has at least 3 different ways to declare dependencies for a provider. Which way to use? Are there performance implications? Unexpected side effects? Um. yes (minification being the big one). So you have to choose carefuly.

I wanted a DI module that was declarative from top to bottom. Where there was only one semantic way to perform each operation. Where there is no need to specify anything about how you structure your code and didn't introduce complexity for what should be returned as a factory or a singleton or whatever. Since I couldn't find anything that fit my criteria - I decided to wire up my own!

Install

yarn (preferred)

yarn add easy-di

npm

npm install --save easy-di

Usage

const easyDi = require('easy-di')

Here's the suggested workflow

  • Load the easy-di library
  • Load all of the dependencies into an easyDi module of your choice
    • Make sure to define a main node for your module
    • Don't worry about the order of declaration (with the exception of resolve)
    • Just declare what you want, where you want, when you want.
  • Finally - resolve your module

Basic Usage

//file main.js
easyDi
    .module('app')
    .main(( one, two, three ) => {
        console.log('node one', one)
        console.log('node two', two)
        console.log('node three', three)
    })


//file one.js
easyDi
    .module('app')
    .define(function one() { return 'ONE'})

//file two.js
easyDi
    .module('app')
    .define(function two(three) { return three + ' AND TWO' })

//file three.js
easyDi
    .module('app')
    .define(function three(one) { return one + ' AND THREE' })


//file resolve.js
easyDi
    .module('app')
    .resolve()
// or
easyDi
    .resolve('app')

    // node one ONE
    // node two ONE AND THREE AND TWO
    // node three ONE AND THREE

Using shared modules

Its possible to define multiple modules and use them respectively in your core application. Be it third party, or just your effort to modularize the code base, using shared modules can be extremely powerful and effective

e.g. lets say you have something like this

lib1/
lib2/
app/

where

  • the lib1 directory defines a module called lib1
  • the lib2 directory defines a module called lib2
  • the app directory contains our application specific module

You can directly use dependencies defined in that library in your module using the following syntax.

Say lib1 defines the doSomething service, we can use it like so

easyDi
  .module('app')
  .include('lib1')
  .define(function root(doSomething) {
    return doSomething() 
  })
  .main(root => {
     console.log(root) // equals the result of doSomething() 
  })
  .resolve()

Defining an injector function

.define()

When defining a dependency the injector functions name is used as the actual name of the dependency. If the name property does not exist/is empty, an error will be thrown

i.e.

// correct

easyDi
  .module('app')
  .define(function hello(world) {
    return world + 1
  })

//or
const hello = (world) => world + 1
easyDi
  .module('app')
  .define(hello)

// incorrect

easyDi
  .module('app')
  .define(function (world) {
    return world + 1
  })

//or
easyDi
  .module('app')
  .define((world) => world + 1)

.main()

The main injector function is exactly the same in syntax as a normal dependency injector function, but does not have to be named, or can have any name.

Think of main as the entry point of the module (the function that will be called by .resolve(). If this is not defined and .resolve() is called, an error will be thrown.

.resolve()

This function will finally resolve the module you want to use. An error will be thrown if the entry point main is not defined.

Features

The biggest take away from this DI module is that the dependencies can declared whenever and wherever. It doesn't matter the order. Even the injector module doesn't need to "prepared" in order to use it. easyDi takes care of that for you.

  • "asynchronous" loading (just call "resolve" when you're ready)
  • no build dependencies
  • no transpiler nonsense
  • auto instantiation of the module/container
  • nothing happens until "resolve" is called
  • LIGHT WEIGHT

Caveats

There is no system of automagically requiring the files you have defined. I suggest using a package like glob to require all the necessary files for the module/libraries you have defined.


API

The complete API and internals documentation is here

Build/Test

Download

git clone https://github.com/navneetgarg123/easy-di.git
cd easy-di

Setup

yarn install

Test

yarn test

Documentation

yarn docs
cd pages/api

Contributing

Issues and pull requests welcome :)

  • Fork it
  • Create your feature branch (git checkout -b feature/my-new-feature)
  • Commit your changes (git commit -am 'Add some feature')
  • Push to the branch (git push origin feature/my-new-feature)
  • Create a new Pull Request