Search code examples
javascriptnode.jsdependency-injectionknex.js

Node library exposing components with dependencies


I'm developing a Node.js ORM library based on Knex, similar to Bookshelf, for use in other personal projects.

Some components of my library require an initialised instance of Knex, so I wrapped them up in an object that gets a Knex instance in the constructor, using a wrapper function to insert the Knex object without having the user inserting it whenever using the library. I tried to do it similar to how Knex and Bookshelf do it, but I found that code hard to read, besides I use ES6 classes, so it's not quite the same.

This is my current code:

const _Entity = require('./Entity.js');
class ORM {
  constructor(knex) {
    // wrapper for exposed class with Knex dependency;
    // knex is the first argument of Entity's constructor
    this.Entity = function(...args) {
      return new _Entity(knex, ...args);
    };
    // exposed class without Knex dependency
    this.Field = require('./Field.js');
  }
}
function init(knex) {
  return new ORM(knex);
}
module.exports = init;

The idea is that the user can use it something like this:

const ORM = require('orm')(knex);
const Entity = ORM.Entity;
const Field = ORM.Field;

const User = new Entity('user', [
  new Field.Id(),
  new Field.Text('name'),
  // define columns...
]);

let user = User.get({id: 5});

It bothers me that Entity is only indirectly exposed and the code looks odd to me. Is there any more elegant or a "standard" way to expose components with dependencies?


Solution

  • Just use a regular function? :

     const _Entity = require('./Entity.js');
     const Field = require('./Field.js');
    
     module.exports = function init(knex){
       return {
         Field,
         Entity: _Entity.bind(_Entity, knex)
      };
    };