It would be much better, if plugins could use e.g. express, out of the box (see #812), in stead of having to add it to their deps.
I admit, that I have no Idea, how to achieve this.
Here is a workaroud: https://github.com/francois2metz/ep_github/blob/master/ep_github.js#L4
Tried it with "ep_etherpad-lite/node_modules/express", just now. This works, too. (! @francois2metz)
how about adding a hook passing an object containing all related modules/external dependencies?
Hm. I think the right hook to do that to is createServer, since it is called once, at startup, by the plugin framework :)
Eh, I’d say this would avoid using one of the (very) useful features of NPM. Sharing libraries vastly increases the surface area of our interface to plugins a lot* – any backwards in-compatible upgrade would necessitate changing not just our code, but probably plugins as well.
*Yes, #701 does just that… something that needs improvement (probably that plugins ought to have their own require context).
@cweider IMHO, this is the one really stupid feature of NPM. It's a nice idea in theory. In practice thou, having multiple copies of the same code, possibly of different versions, breaks any kind of singleton pattern, not to mention what happens when two versions of the same code uses slightly incompatible ways to talk to the same external system (e.g. different expectations of database schema for the same database).
For a practical example: What happens if you let plugins register extra menu items that activates some functionality, and then one such plugin is required as a dependency for two other plugins? You get two buttons, with the same, or slightly different functionality.
I have been trying to figure out how to solve this practical issue, but there is no sane way.
Multiple library versions in the same application is madness.
Oy, all I could do was facepalm reading that NPM discussion about peer decencies (something about making it easy for your dependencies to modify your state… and singletons… but that’s just me). In the meantime, dependency injection is the more pedestrian way to accomplish this. Etherpad would export an interface to the plugin providing it with a means to get access to objects that are safe (shared objects, peer plugins, etc.) to share.