Question

I'm pretty new to Node.JS development and I'm trying to create a Hubot adapter.

The hubot module exports a class named TextMessage I need to use. In my adapter, I create an instance of this and pass it to the running robot like so:

{Adapter, TextMessage} = require 'hubot'
class MyAdapter extends Adapter
  onNewMessage: (text) =>
    @receive new TextMessage text

However, in Hubot's own code it is checking that my message is an instanceof TextMessage. When I run a bot and use my adapter, this check always fails.

The project structure is laid out like this:

my-bot
 |- node_modules
    |- my-adapter
    |  |- node_modules
    |  |  |- hubot
    |- hubot  

As a result require('hubot') in my-adapter is giving me a different copy of the hubot module as the one given to my-bot.

I'm pretty sure I'm not understanding some fundamental concept of Node modules here. What am I doing wrong?

Was it helpful?

Solution

The reason it is designed this way is so that it's possible for a module to always get a "fresh" version (that has not been modified by any libraries such as your one). Generally, if you require() one of your dependencies, then you should be able to rely on default behaviour for that module. (The alternative is unpredictable and possibly insecure.)

If the purpose of your module is to adapt another module, then you should either:

Return a modified module

For example, your module might do:

module.exports = require('hubot');
// ... your custom modifications

Or:

var hubot = module.exports.hubot = require('hubot');

This means that the app itself wouldn't depend on hubot, but only your module.

Not list hubot as a dependency for your adapter

Node.js require() calls cascade up the path - so if you simply don't install hubot as a dependency, then you can still require() it, and it will use the version from the app.

This means that it's possible to install your module without installing hubot, thus causing problems - but on the other hand, it also allows multiple modules to modify the same base module.

Personally, I'd opt for the second option.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top