I'm requiring a library in NodeJS which has a self-invoking function, that results an error because it looks for an object which is not initialized at that moment .
I want to dynamically require this library when that object is initialized.
Is there any way to dynamically require/ load a library ?
This is the part of library required :
https://github.com/sakren/node-google-maps/blob/develop/lib/Google.js#L5
Actually I want to require when the window object is present (client-side rendering).
So something like this :
'use strict';
var React = require('react');
var Map = require('./map.jsx');
var Common = require('../common/common');
var MapStatic = require('./map-static.jsx');
exports.type = function() {
return 'map';
};
exports.jsx = function(data) {
if (Common.isServerSide()) {
return (<MapStatic data={data}/>);
} else {
return (
<Map data={data}/>
);
}
};
exports.transform = require('./map-transform.js');
The reason the code looks weired is that I'm using react.
In nodeJS require can be used anywhere at anytime whithout much limitations AFAIK.
Which error is thrown once you require at runtime ?
In your else branch.
Try the following.
requires = {}
function getter(key) {
if(!requires[key]){
requires[key] = require(key)
}
return requires[key]
}
Related
I'm having trouble understanding the difference between exporting modules like:
module.exports.getUserIP = function getUserIP(req) {
var ip = req.headers['x-forwarded-for'];
return ip;
}
Or just declaring it:
function getUserIP(req) {
// retrieve user IP from req object
// Build this function to be more accurate/use more sources.
var ip = req.headers['x-forwarded-for'];
return ip;
}
and exporting at the bottom:
module.exports = { getUserIP }
or even:
module.exports = {getUserIP:getUserIP}
or
module.exports = {'getUserIP':getUserIP}
My problem is: when i call the function getUserIP from another file:
var mainbody = require('./app.js');//getUserIP is in here.
const gl = require('geoip-lite');
var ax = require('axios');
module.exports.getloc = function getloc(req, ip, property) {
//return location from IP.
if (req) {
var ipGuest = mainbody.getUserIP(req); //HERE
} else {
var ipGuest = ip;
}....
I get an error message:
Error Message
However, when I use the FIRST method to export the function:
module.exports.getUserIP = function getUserIP(req) {
var ip = req.headers['x-forwarded-for'];
return ip;
}
Then it works perfectly.
What's the difference?
Better way is to use
module.exports = { getUserIP: getUserIP }
This way you can just look at the export statement at the end of your file and know which functions are being exported from a particular file
The module.exports = {getUserIP}; is nothing but a shorthand of the above syntax(ES6 Magic). What it typically does is allows you to write this way { getUserIP } if the key name to be same as function/variable name like { getUserIP: getUserIP } where getUserIP can be a variable or a function or a ES6 class.
All the examples you show will work properly, but they do have some different affects.
By default module.exports is already initialized to an empty object. So, when you do something like this:
module.exports.getUserIP = function() {...}
You are assigning a new property to the existing object that module.exports already pointed to. One advantage of this scheme is that you can easily add more properties the same way.
module.exports.getUserRegion = function() {}
This will add one more property to that same object without disturbing the first one you already added.
On the other hand, all of these are identical:
module.exports = {getUserIP: getUserIP}
module.exports = {'getUserIP':getUserIP}
module.exports = { getUserIP } // ES6 shorthand for the previous syntax
and, they all end up with the same result as each other, but they all replace module.exports with a new object that has your one new property in it.
If you then tried to add another property:
module.exports = {getUserRegion};
That would again assign a whole new object to module.exports and you would have just wiped out the object that previously had getUserIP on it. When assigning a new object, you would typically assign an object that had all your properties on it:
module.exports = {getUserIP: function() {...}, getUserRegion: function() {...}};
Thus, not wiping out something you had already put there.
All of your schemes should work fine as long as you aren't overwriting module.exports with a new object and thus overwriting the object that already had some of your methods on it.
To understand this exporting modules concept, just think module.export is a simple object. you can bind anything to that object as do with normal javascript objects.
Finally when you require that module by require('path to js') you will get that exported object. If you export number of items in your module you can return them back by giving the names of the tag.
require('Something') //working fine
require(`${dynamicName}`) //not work with node prompt for out of memory
Can advise on how to dynamically require a module based on variable 'dynamicName' ?
You can always override require with your own version, since it is a function.
function setupMyRequire() {
var tmpreq = global.require;
global.require = function(name) {
// parse name here
console.log('will require', name);
tmpreq(name);
};
}
I want to somehow create a global singleton module. I'm using it as the context module where I can reference it in any of my modules.
I'll use it to get to my gateway (repository) module for use in other modules like my business object modules etc. So for example let's say I have:
myBusinessModule.js
module.exports = {
find: function(id){
var user = context.userGateway.find(id);
}
};
So I want to be able to use the context singleton to get at other modules in my node app.
Just like the same thing here, this is Java but same concept I want to do something like this in Node.JS: CleanCodeCaseStudy
Based on your comment, to me it looks like you want something like this. Please correct me if i wrongly understood your requirement.
Access with require()
context.js
var context = {};
context.userGateway = require('../path/to/userGateway/module');
module.exports.context = context;
=====================================================================================
//usage in reference file
var context = require('/path/to/context/file');
module.exports = {
find: function(id){
var user = context.userGateway.find(id);
}
};
Access without require()
var context = {};
context.userGateway = require('../path/to/userGateway/module');
GLOBAL.context = context; // makes your context object accessible globally, just like, console, require, module etc.
=====================================================================================
//usage in reference file
module.exports = {
find: function(id){
var user = context.userGateway.find(id);
}
};
Consider I want to expose a method called Print
Binding method as prototype:
File Saved as Printer.js
var printerObj = function(isPrinted) {
this.printed = isPrinted;
}
printerObj.prototype.printNow = function(printData) {
console.log('= Print Started =');
};
module.exports = printerObj;
Then access printNow() by putting code require('Printer.js').printNow() in any external .js node program file.
Export method itself using module.exports:
File Saved as Printer2.js
var printed = false;
function printNow() {
console.log('= Print Started =');
}
module.exports.printNow = printNow;
Then access printNow() by putting code require('Printer2.js').printNow() in any external .js node program file.
Can anyone tell what is the difference and best way of doing it with respect to Node.js?
Definitely the first way. It is called the substack pattern and you can read about it on Twitter and on Mikeal Rogers' blog. Some code examples can be found at the jade github repo in the parser:
var Parser = exports = module.exports = function Parser(str, filename, options){
this.input = str;
this.lexer = new Lexer(str, options);
...
};
Parser.prototype = {
context: function(parser){
if (parser) {
this.contexts.push(parser);
} else {
return this.contexts.pop();
}
},
advance: function(){
return this.lexer.advance();
}
};
In the first example you are creating a class, ideally you should use it with "new" in your caller program:
var PrinterObj = require('Printer.js').PrinterObj;
var printer = new PrinterObj();
printer.PrintNow();
This is a good read on the subject: http://www.2ality.com/2012/01/js-inheritance-by-example.html
In the second example you are returning a function.
The difference is that you can have multiple instances of the first example (provided you use new as indicated) but only one instance of the second approach.
I am playing around and learning about vows with a personal project. This is a small client side library, with testing done in vows. Therefore, I must build and test a file that is written like this:
(function(exports) {
var module = export.module = { "version":"0.0.1" };
//more stuff
})(this);
In my testing (based off of science.js, d3, etc.) requires that module like so:
require("../module");
I continued to get a "module not defined error" when trying to run the tests, so I went to a repl and ran:
require("../module")
and it returned:
{ module: { version: "0.0.1" } }
I realize I could do something like:
var module = require("../module").module;
but feel like I am creating a problem by doing it that way, especially since the libraries that I based this project on are doing it in the format I described.
I would like for my project to behave similar to those which I based it off of, where:
require("../module");
creates a variable in this namespace:
module.version; //is valid.
I have seen this in a variety of libraries, and I am following the format and thought process to the T but believe I might be missing something about require behavior I don't know about.
There is no problem creating it this way. Modules define what they return in the module.exports object. By the way, you don't actually need self executing functions (SEF), there is no global leakage like in browsers :-)
Examples
module1.js:
module.exports = {
module: { 'version': '0.1.1' }
};
main.js:
var module1 = require( './module1.js' );
// module1 has what is exported in module1.js
Once you've understood how this works, you can easily export the version number right away if you want to:
module1.js:
module.exports = '0.1.1';
main.js:
var module1 = require( './module1.js' );
console.log( module1 === '0.1.1' ); // true
Or if you want some logic, you can easily extend your module1.js file like this:
module.exports = ( function() {
// some code
return version;
} () ); // note the self executing part :-)
// since it's self executed, the exported part
// is what's returned in the SEF
Or, as many modules do, if you want to export some utility functions (and keep others "private"), you could do it like this:
module.exports = {
func1: function() {
return someFunc();
},
func2: function() {},
prop: '1.0.0'
};
// This function is local to this file, it's not exported
function someFunc() {
}
So, in main.js:
var module1 = require( './module1.js' );
module1.func1(); // works
module1.func2(); // works
module1.prop; // "1.0.0"
module1.someFunc(); // Reference error, the function doesn't exist
Your special case
About your special case, I wouldn't recommend doing it like they're doing.
If you look here: https://github.com/jasondavies/science.js/blob/master/science.v1.js
You see that they're not using the var keyword. So, they're creating a global variable.
This is why they can access it once they require the module defining the global variable.
And by the way, the exports argument is useless in their case. It's even misleading, since it actually is the global object (equivalent of window in browsers), not the module.exports object (this in functions is the global object, it'd be undefined if strict mode were enabled).
Conclusion
Don't do it like they're doing, it's a bad idea. Global variables are a bad idea, it's better to use node's philosophy, and to store the required module in a variable that you reuse.
If you want to have an object that you can use in client side and test in node.js, here is a way:
yourModule.js:
// Use either node's export or the global object in browsers
var global = module ? module.exports : window.yourModule;
( function( exports ) {
var yourModule = {};
// do some stuff
exports = yourModule;
} ( global ) );
Which you can shorten to this in order to avoid creating the global variable:
( function( exports ) {
var yourModule = {};
// do some stuff
exports = yourModule;
} ( module ? module.exports : window.yourModule ) );
This way, you can use it like this on the client-side:
yourModule.someMethod(); // global object, "namespace"
And on the server side:
var yourModule = require( '../yourModule.js' );
yourModule.someMethod(); // local variable :-)
Just FYI, .. means "parent directory". This is the relative path of where to get the module. If the file were in the same directory, you'd use ..