I have a module that I use for node and (now) react-native. I'd like to selectively export code depending on which platform it's going to run on. If you can get this to run on the device, you've solved the problem.
module:
if(!react_native){
exports.fs = require('fs');
}
exports.print = function(str){ console.log(str); }
on device:
var m = require('module');
m.print("hello world.");
Is there any way to do this?
I don't want to create two separate modules that only differ in index.js if I don't have to.
Thanks!
A simple check - loading the basic package:
var isNative = false;
var Platform;
try {
Platform = require('react-native').Platform;
isNative = true;
} catch(e) {}
if (isNative) {
console.log(Platform.OS, Platform.Version);
} else {
console.log('node');
}
Related
I am writing a module that will be used as a dependency for Node.js apps. In some cases, it will be a dependency of a dependency, which means the path resolution will change, and currently I am having a problem with that. Namely, when my module is a dependency of a dependency, my module will still look to the app root, not the root of the dependency.
I think the shortest way to ask a question on how to solve this is to find out the best way to determine if the module is a dependency or not.
So the way to do that would be to get the __dirname of the file in the index of my module and then navigate up one directory to see if that directory is named node_modules.
Is there a better way to do this? Is there a better way to determine if the code being invoked is being invoked from a dependency of the app or from the app itself?
Visually speaking, it looks like this
--app
---/node_modules
-----/A
-----/B
my module is called A
A could be used by app, or it could be used by B
if it's used by app, I can use the app-root-path module to quickly determine the root. But if my module is used by B, how will I know that? It will matter for resolving paths.
Here is the entiriety of the code in my module:
var appRoot = require('app-root-path');
var path = require('path');
var configs = {};
function checkIfDependency(){
var temp = path.resolve(path.normalize(__dirname + '/../'));
return path.basename(temp) === 'node_modules';
}
module.exports = function (identifier, pathToProvider) {
if (String(identifier).indexOf('*') < 0) {
throw new Error('did not pass in an identifier to univ-config');
}
if (configs[identifier]) {
return configs[identifier];
}
else {
if (pathToProvider) {
try {
var configPath;
if (path.isAbsolute(pathToProvider)) { //consumer of this lib has been so kind as to provide an absolute path, the risk is now yours
configPath = path.normalize(pathToProvider);
}
else if(checkIfDependency()){ //univ-config is being invoked from a dependency
configPath = path.normalize(??? + '/' + pathToProvider);
}
else{ //univ-config is being invoked from an app
configPath = path.normalize(appRoot + '/' + pathToProvider);
}
var f = require(configPath);
return configs[identifier] = f();
}
catch (err) {
throw new Error('univ-config could not resolve the path to your config provider module - given as:' + pathToProvider);
}
}
else {
throw new Error('no config matched the identifier but no path to config provider was passed to univ-config');
}
}
};
I want to import a dependency of a dependency. For example, I want to import jade-load directly into my app:
my-app
┗━jade
┗━jade-load
I could do require('jade/node_modules/jade-load'), but this won't work if the node_modules tree has been flattened or deduped.
I thought of using require.resolve() to find out where jade-load really is, but there doesn't seem to be a way to tell it the starting point for the resolution. I need to be able to say "require jade-load from wherever jade is".
NB. I do not want to install jade-load as a direct dependency of my app; the point is to import the same instance that jade uses, so I can monkeypatch it.
I guess you may want to use proxyquire for managing dependencies of required modules. You can set proxyquire to globally override methods of the submodule when it will be loaded.
main.js
var proxyquire = require('proxyquire');
// use default childModule properties and methods unless they are redefined here
var childModuleStub = {
/* redefine here some necessary methods */
'#global': true
};
// parent module itself does't require childModule
var parentModuleStubs = {
'./childModule': childModuleStub
};
var parentModule = proxyquire('./parentModule', parentModuleStubs);
var result;
result = parentModule.exec();
console.log(result);
childModuleStub.data.sentence = "Overridden property.";
result = parentModule.exec();
console.log(result);
childModuleStub._exec = function () {
return "Overridden function.";
};
result = parentModule.exec();
console.log(result);
parentModule.js
var intermediateLibrary = require('./intermediateLibrary');
module.exports = {
exec: function() {
return intermediateLibrary.exec();
}
};
intermediateLibrary.js
var childModule = require('./childModule');
module.exports = {
exec: function() {
return childModule._exec();
}
};
childModule.js
var lib = {};
lib.data = {};
lib.data.sentence = "Hello, World!";
lib._exec = function () {
return lib.data.sentence;
};
module.exports = lib;
Results:
Hello, World!
Overridden property.
Overridden function.
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]
}
I am using nodejs in my meteor app and I added packages using mrt add npm and then in my client directory in packages.json I added skimlinksjs and its version and it is added to my app.
When I tried to using them in my app in server side code like this,
var res;
var skim = Meteor.require('skimlinksjs');
var apili = Meteor.require('/config.js');
skim.setup(apili.key);
skim.query({
searchFor: "title:\"moto g\"",
fq: "country:US"
}, function(err,data) {
res=data.skimlinksProductAPI.numFound;
}
);
return res;
and my config.js file is like this
module.exports = {
key: "xxxxxxx"
}
whenI'm running this application it is showing error like
module not defined
What went wrong with my code or is there any need to install other packages?
I just got the answer
Write this function in server side code
function returnAllResult()
{
var skimlinks = Meteor.require('skimlinksjs');
skimlinks.setup("xxx");
var skimlinks_query = Async.wrap(skimlinks.query);
var result = skimlinks_query({
searchFor: "title:\"moto g\"",
fq: "country:US",
rows:5
});
return result;
}
to know about asynchronous functions watch this
and then in my server side methods call this
apiresult:function()
{
var response = returnAllResult();
return response.skimlinksProductAPI.products[0].merchant;
}
that's it working fine now. Hope this helps someone
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.