Skip to content

Instantly share code, notes, and snippets.

@sevcsik
Last active February 15, 2022 09:38
  • Star 43 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save sevcsik/9207267 to your computer and use it in GitHub Desktop.
Sharing modules between NodeJS and AngularJS

They say that one of the pros of NodeJS is that you use the same language on the back-end and the front-end, so it's easy to share code between them. This sounds great in theory, but in practice the synchronous dependency handling in NodeJS works completely different than any client-side frameworks (which are asynchronous).

Usually that means that you end up copy-pasting your code between your NodeJS sources and your client-side sources, or you use some tool like Browserify, which is brilliant, but they add an extra step in the build process and most likely will conflict with the dependency handling of the framework of your choice (like AnularJS DI). I couldn't look in the mirror if I would call that code sharing.

Fortunately, with a couple of lines of boilerplate code, you can write a module which works in NodeJS and AngularJS as well without any modification.

No globals in the front-end, and dependencies will work. The isNode and isAngular vars are in the closure, so they can be used to switch between platform-dependent code blocks (such as angular.extend and node.extend).

Since you'd need the isAngular branch and the isNode branch anyway, and you'd also need the wrapper function on the front-end, there's only 4 additional lines needed make your module compatible with both -ends.

Porting to RequireJS should be similar, since they both use wrapper functions and dependencies as function arguments.

I'm yet to find a way to document them seamlessly though.

// We will pass these to the wrapper function at the end of the file
(function(isNode, isAngular) {
// This wrapper function returns the contents of your module,
// with dependencies
var SilverBulletModule = function(Bullet, Silver) {
var SilverBullet = function() {
// something awesome happens here
};
return SilverBullet;
};
if (isAngular) {
// AngularJS module definition
angular.module('app.silverbullet', ['app.silver', 'app.bullet']).
factory('SilverBullet', ['Bullet', 'Silver', SilverBulletModule]);
} else if (isNode) {
// NodeJS module definition
module.exports = SilverBulletModule(
require('bullet.js'),
require('silver.js')
);
}
})(typeof module !== 'undefined' && module.exports,
typeof angular !== 'undefined');
@bastianwegge
Copy link

@sinsunsan

(function(isNode,isAngular){ // this gets resolved at the bottom of the function before it's called

})(typeof module !== 'undefined' && module.exports, // this is the isNode variable at the top
typeof angular !== 'undefined'); // this is the isAngular variable at the top

The whole expression resolves to either a nodejs-requirable module (as you mentioned before, var sharedModule = require('../.../silverbullet.js');) or as a module on the window object. In latter case you can just require the module using a link in html <script src="./silverbullet.js"></script> and then use it.

@1mike12
Copy link

1mike12 commented Jun 17, 2016

I'm using webstorm and the self running function confused it, and would cause it to highlight all my methods as not found. So here's a modified version, that might be clearer as well for first comers who are trying to figure out what is going on in the original code snippets.

var Singleton = new function(){
    var self = this;

    self.methodTheIDECanUnderstand = function(){
        return "yipppeeee"
    }
};

//shared code logic
var isAngular = typeof angular !== "undefined";
var isNode = typeof module !== 'undefined' && module.exports;

if (isAngular) {
    // AngularJS module definition
    app.factory('MySingleton', function(){
        return Singleton
    });
} else if (isNode) {
    // NodeJS module definition
    module.exports = Singleton;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment