From a performance perspective, is there any difference between invoking code by wrapping it in a function and then exporting it:
function doSomething () {
// doing something here
}
module.exports = doSomething();
And just requiring it without any exports? like this:
myModule.js
// Code doing something
file that requires the module:
var doSomething = require('./myModule');
And if the purpose of the code inside the module is to run just once, do I need to store it in a variable?
If you don't need the return value of that function, then you don't have to store it in a variable.
The difference with:
function doSomething () {
// doing something here
}
module.exports = doSomething();
and using:
var x = require('module');
var y = require('module');
vs.
function doSomething () {
// doing something here
}
module.exports = doSomething;
and using:
var x = require('module')();
var y = require('module')();
is that in the first case, the function will be run only once, while in the second case the function will be run twice.
The difference is that if you just include it without module.exports, then the code will execute immediately but be private to the module. You can only access the data if you export it somehow, with module.exports. It can be either a function or a Javascript Object. Essentially, you can view everything within the module as being completely hidden from everything else in your application.
The only shortcut that I know of is for JSON files. If you look here: Module.exports vs plain json for config files, you can see that you can require('file.json') and it will replace the contents of the json file with a Javascript object that you can then use in your application.
Related
I want to extend a current Node.js module with some global config setting being configured once without breaking current usages of this module.
This is the signature of the module:
const myFunction = function(someOptions) { ... };
module.exports = myFunction;
Usage is
const myFunction = require('myfunction');
const result = myFunction(options);
Now I want to set some options on application startup to be used by the module myfunction whenever being required without breaking current usages of the module myfunction.
If possible, I want to avoid using Node.js global.
Functions in JavaScript are just objects, so you can give them properties. This is a little hacky, but it could certainly work for you:
// greeter.js
function sayHello() {
const message = sayHello.message || "Hi";
console.log(message);
}
module.exports = sayHello;
You can now set the config of this function globally as follows:
const sayHello = require("./greeter.js");
sayHello.message = "S'up dawg";
Any subsequent calls to sayHello() after the code above is executed will use the overridden message. This works because calls to require() are cached, so each time you require(./greeter.js); you're getting back exactly the same function object.
i am working on a project in which a nodejs program calls another program in a separate file.
this is how i've added the two:
var ocr = require('./index.js'); //this imports the file
var arr = ocr.ocr_pan(); //this calls the function in that file
am not sure but I guess the problem is that the process resumes before ocr.ocr_pan() returns the result and var arr becomes undefined.
or there is some problem in returning the result from ocr.ocr_pan()
I simply use return.
and I have also tried this : How to return array from module in NodeJS
didn't work
what more can be done?
Assuming that this file is the same directory as index.js file, code in index.js should be something like this:
// Write your function
var ocr_pan = function() {
// Do whatever you like
return result;
};
// Export it, make publicly visible to other files
module.exports = {
ocr_pan: ocr_pan
};
I am currently testing a module in isolation using proxquire to overwrite a require of this module.
Overwriting a path of a require works fine with proxyquire. For example:
var bar = require('./bar');
But can you use proxyquire also to overwrite just a specific function of a module which is required in the module to test? So something like:
var bar = require('./foo').bar();
I need to stay at proxyquire for this since I am using it for mocking a http-request happening in another layer of the architecture. But in case of the test I need to mock the time for "now" in the module as well.
So currently I have this:
var uraStub = sendMockRequest(paramListOfCheckin, queryList);
var setNowStub = function(){ return 1425998221000; };
var checkin = proxyquire('../src/logic/logicHandlerModules/checkin', {
'../../persistence/ura' : uraStub,
'./checkin.setNow' : setNowStub
});
checkin.checkin(...)
The implementation of setNow is:
var setNow = function(){
return new Date().getTime();
};
var checkin = function (...) {
var now = require('./checkin').setNow();
Obviousley './checkin.setNow' : setNowStub in proxyquire doesn't work, since this is the wrong path. But using './checkin'.setNow() : setNowStub also doesn't work because of wrong syntaxis in the object-definition.
Any suggestions?
Thanks in advance!
What you are looking for is the noCallThru() and callThru() methods. https://github.com/thlorenz/proxyquire#preventing-call-thru-to-original-dependency
By default proxyRequire will call through to the mocked dependency which will allow you to pick the methods that you want to overwrite with your own custom function.
So if a dependency in the path '../foo' has a method bar() and fooBar() you would be able to mock out just bar by doing.
proxyquire.callThru();
var fooFunc = proxyquire('../foo', {
bar: () => return 'bar'
})
Now bar() will hit your custom overwritten funtion while fooBar() will be called as normal.
I am trying to test a function in a module. This function ( I will refer to it as function_a ) calls a different function ( function_b ) within the same file. So this module looks like this:
//the module file
module.exports.function_a = function (){
//does stuff
function_b()
};
module.exports.function_b = function_b = function () {
//more stuff
}
I need to test function_a with a specific result from function_b.
I would like to override function_b from my test file, then call function_a from my test file, resulting in function_a calling this override function instead of function_b.
Just a note, I have tried and succeeded in overriding functions from separate modules, like this question, but that is not what I am interested in.
I have tried the code below, and as far as I know, doesn't work. It does illustrates what I am going for, though.
//test file
that_module = require("that module")
that_module.function_b = function () { ...override ... }
that_module.function_a() //now uses the override function
Is there a correct way to do this?
From outside a module's code, you can only modify that module's exports object. You can't "reach into" the module and change the value of function_b within the module code. However, you can (and did, in your final example) change the value of exports.function_b.
If you change function_a to call exports.function_b instead of function_b, your external change to the module will happen as expected.
You can actually use the package rewire. It allows you to get and set whatever was declared in the module
foo.js
const _secretPrefix = 'super secret ';
function secretMessage() {
return _secretPrefix + _message();
}
function _message() {
return 'hello';
}
foo.test.js
const rewire = require('rewire');
// Note that the path is relative to `foo.test.js`
const fooRewired = rewire('path_to_foo');
// Outputs 'super secret hello'
fooRewired.secretMessage();
fooRewired.__set__('_message', () => 'ciao')
// Outputs 'super secret ciao'
fooRewired.secretMessage();
Writing the simplest module we could, we write into hello.js:
var hello = function(){
console.log('hello');
};
exports = hello; \\ Doesn't work on Amazon EC2 Ubuntu Instance nor Windows Powershell
I run Node and require the module
var hello = require('./hello');
hello;
and an empty array {} gets returned when I'm supposed to get [Function].
I tried replacing exports with module.exports, but this doesn't work on my Windows Powershell. It does work on my Amazon EC2 Ubuntu Instance, so why doesn't exports work? Has the API changed? And what could possibly be happening with Powershell that neither of these work?
I know Windows isn't the most desirable development environment, but I can't get my head around such a simple mishap.
EDIT
exporting with ES6 is a little nicer
export const hello = function(){
console.log('hello');
};
importing will look like
import {hello} from './file';
Original answer
You'll want to use module.exports
var hello = function(){
console.log('hello');
};
module.exports = hello;
If just exporting one thing, I'll usually do it all in one line
var hello = module.exports = function() {
console.log('hello');
};
Extras
If you use a named function, in the event an error occurs in your code, your stack trace will look a lot nicer. Here's the way I would write it
// use a named function ↓
var hello = module.exports = function hello() {
console.log("hello");
};
Now instead of showing anonymous for the function name in the stack trace, it will show you hello. This makes finding bugs so much easier.
I use this pattern everywhere so that I can debug code easily. Here's another example
// event listeners ↓
mystream.on("end", function onEnd() {
console.log("mystream ended");
};
// callbacks ↓
Pokemon.where({name: "Metapod"}, function pokemonWhere(err, result) {
// do stuff
});
If you want to export multiple things, you can use exports directly, but you must provide a key
// lib/foobar.js
exports.foo = function foo() {
console.log("hello foo!");
};
exports.bar = function bar() {
console.log("hello bar!");
};
Now when you use that file
var foobar = require("./lib/foobar");
foobar.foo(); // hello foo!
foobar.bar(); // hello bar!
As a final bonus, I'll show you how you can rewrite that foobar.js by exporting a single object but still getting the same behavior
// lib/foobar.js
module.exports = {
foo: function foo() {
console.log("hello foo!");
},
bar: function bar() {
console.log("hello bar!");
}
};
// works the same as before!
This allows you to write modules in whichever way is best suited for that particular module. Yay!
The reason exports is not working is because of the reference conflict. The top variable in each file is module which has a property module.exports. When the module is loaded new variable is created in the background. Something like this happens:
var exports = module.exports;
Obviously exports is a reference to module.exports, but doing
exports = function(){};
forces exports variable to point at function object - it does not change module.exports. It's like doing:
var TEST = { foo: 1 };
var foo = TEST.foo;
foo = "bar";
console.log(TEST.foo);
// 1
Common practice is to do:
module.exports = exports = function() { ... };
I have no idea why it doesn't work under Windows Powershell. To be honest I'm not even sure what that is. :) Can't you just use native command prompt?