Write a module that works both in nodejs and requirejs - node.js

I wrote a small parser that currently works in node app, but wondering if there is a way that I can make a module that will work both in NodeJS app and client side app that uses requirejs?
path/to/lib/index.js
function someRandom(strings) {
// we are doing something here
return strings
}
exports.someRandom = someRandom;
Right now I'm getting this in client-side
Uncaught ReferenceError: exports is not defined
I know that I can use node requirejs and then change the structure to use define but is there other way without adding node requirejs?
This is my js/main.js file
require(["path/to/lib/index"], function(something) {
// will do something here
});

The way I prefer to do it is to write all my modules in the AMD syntax (use define) and use amd-loader to load them in Node. Note that this solution is not using RequireJS, even though the AMD syntax is used.
However, there's a way to do it without having to use the AMD syntax. You can use r.js to wrap your Node modules. For instance, if you put your tree of Node modules in in, you can do:
$ r.js -convert in out
This will create in out a tree of files that correspond to those in in but wrapped with the define call. You can then load these in the browser using RequireJS. There are limitations. Some are obvious, like not being able to use the Node modules that depend on the Node runtime (like fs, child_process, etc.). Some are more subtle, like the fact that you can't use require(foo) where foo is a variable (RequireJS will handle only string literals there). See the documentation for the details.

Related

How do the core modules in node.js work? (https://github.com/nodejs/node/blob/master/lib)

Does the node interpreter look for core modules (let's say "fs") within the node binary? If yes, are these modules packaged as js files. Are the core modules that are referenced within our code converted to c/c++ code first and then executed? For example, I see a method in the _tls_common.js (https://github.com/nodejs/node/blob/master/lib/_tls_common.js) file called "loadPKCS12" and the only place that I see this method being referenced/defined is within the "node_crypto.cc" file (https://github.com/nodejs/node/blob/master/src/node_crypto.cc). So how does node link a method in javascript with the one defined in the c/c++ file?
here is the extract from the _tls_common.js file that makes use of the "loadPKCS12" method:
if (passphrase) {
c.context.loadPKCS12(buf, toBuf(passphrase));
} else {
c.context.loadPKCS12(buf);
}
}
} else {
const buf = toBuf(options.pfx);
const passphrase = options.passphrase;
if (passphrase) {
c.context.loadPKCS12(buf, toBuf(passphrase));
} else {
c.context.loadPKCS12(buf);
There are two different (but seemingly related) questions asked here. The first one is: "How the core modules work?". Second one being "How does NodeJS let c++ code get referenced and executed in JavaScript?". Let's take them one by one.
How the core modules work?
The core modules are packaged with NodeJS binary. And, while they are packaged with the binary, they are not converted to c++ code before packaging. The internal modules are loaded into memory during bootstrap of the node process. When a program executes, lets say require('fs'), the require function simply returns the already loaded module from cache. The actual loading of the internal module obviously happens in c++ code.
How does NodeJS let c++ code get referenced in JS?
This ability comes partly from V8 engine which exposes the ability to create and manage JS constructs in C++, and partly from NodeJS / LibUV which create a wrapper on top of V8 to provide the execution environment. The documentation about such node modules can be accessed here. As the documentation states, these c++ modules can be used in JS file by requiring them, like any other ordinary JS module.
Your example for use of c++ function in JS (loadPKCS12), however, is more special case of internal c++ functionality of NodeJS. loadPKCS12 is called on a object of SecureContext imported from crypto c++ module. If you follow the link to SecureContext import in _tls_common.js above, you will see that the crypto is not loaded using require(), instead a special (global) method internalBinding is used to obtain the reference. At the last line in node_crypto.cc file, initializer for internal module crypto is registered. Following the chain of initialization, node::crypto::Initialize calls node::crypto::SecureContext::Initialize which creates a function template, assigns the appropriate prototype methods and exports it on target. Eventually these exported functionalities from C++ world are imported and used in JS-World using internalBinding.

Using node module in angularjs?

What's the best practice for using external code, e.g. code found in node modules, in angular?
I'd like to use this https://www.npmjs.com/package/positionsizingcalculator node module in my angular app. I've created an angular service intended to wrap the node module, and now I want to make the service use the node module.
'use strict';
angular.module('angularcalculator')
.service('MyService', function () {
this.calculate = function () {
return {
//I want to call the node module here, whats the best practice?
};
}
});
To do this, I would crack open the package and grab the .js out of it. This package is MIT license, so we can do whatever we want. If you navigate to /node_modules/positionsizingcalculator/ you'll find an index.js. Open that up and you'll see the moudle export, which takes a function that returns an object.
You'll notice this is an extremely similar pattern to .factory, which also takes a function that returns an object (or constuctor, depending on your pattern). So I'd do the following
.factory('positionsizingcalculator', function(){
basicValidate = function (argument) {
... //Insert whole declaration in here
return position;
})
and the inject it where you need it:
.controller('AppController', function(positionsizingcalculator){
//use it here as you would in node after you inject it via require.
})
--
Edit: This is good for one off grabs of the JS, but if you want a more extensible solution, http://browserify.org/ is a better bet. It allows you to transform your requirements into a single package. Note that this could result in pulling down a lot more code that you might otherwise need, if you make one require bundle for your whole site, as this is not true AMD, and you need to to load everything you might want one the client, unless you make page specific bundles.
You'd still want to do the require in a factory and return it, to keep it in angular's dependency injection framework.

What is the best way to configure an AMD/Require.js module before it is loaded into other modules?

Currently I am using Marionette which registers itself as an AMD module called "marionette". Before it gets loaded into other modules, I want to set some configurations on it. My only thought as of now is to do this:
// configuredMarionette.js
define(["marionette"], function(Marionette) {
// modify Marionette here
return Marionette;
});
Then, in each of my modules that need marionette, I set "configuredMarionette" as the dependency instead of "marionette" so that I get the configured version. Is there any other way around this that is cleaner?
It may be more useful if you rename 'configuredMarionette' to 'marionette' and use 'orignalMarionette' for original one.
It will be easy to use any other module which has a dependency to 'marionette' to use configured one.

Load a chaplin module synchronously

I'm trying to just load the event_broker module in the chaplinjs . I am able to to do by doing something like
require(["underscore", "chaplin"], function(_, chaplin)
{
var eventBroker = _({}).extend(chaplin.EventBroker);
});
But, this is not good enough in my case. I need to be able to load the event_broker module synchronously. I know that is what require designed to do. Is there a way to do that?
I know that is what require designed to do.
No, that's not what RequireJS is designed to do. (Did you forget to put "not" in there?) RequireJS is designed to load modules asynchronously.
I would normally suggest loading Chaplin through a script element because that would be synchronous but, after looking at the code of Chaplin, I see that it fails with throw new Error('Chaplin requires Common.js or AMD modules'); if it does not detect a CommonJS or AMD environment.
Almond can be used to load bundles of AMD modules synchronously so this may be an option for you.

Is there dojo.hitch equivalent in node.js

I am looking for a function that kind bind the 'this' of a function. Although it is easy to write one, I want to be sure that it is not part of any popular module in node.js environment before I write or use the one from dojo.
(function() {
alert(this.toString());
}).bind(new String("Man ES5 is awesome.")).call();
Function.prototype.bind[docs]
Node.js runs on V8. V8 is fully ES5 compliant.

Resources