I want to have a global script that I can include system wide for some helper files.
This is the helper file (helper.js):
async function hasStock() {
}
// Export it to make it available outside
module.exports.hasStock = hasStock;
But now the problem, I have a model that I give in the index.js, the model is only available there:
app.use('/api/parts', require('./routes/part.js')(app, models));
But I also need that model (models) at my helper.js file.
So I thought I need to do this in part.js (from /api/parts):
module.exports = function (app, models) {
require("../helpers/helper.js")(models);
}
But that isn't also good I think. What is a good solution to include the models (models object only available in the index.js) and to use this system wide in helpers.js?
You should try to export the function hasStock by following method ,
In your helper.js file
const anyObjectName = {
hasStock : async function hasStock {
}
}
//like this export , you can use this object and it's function anywhere .
module.exports = anyObjectName;
In your part.js (from /api/parts):
var anyObjectName = require('../helpers/helper.js');
//now you can access the hasStock function in part.js file like
anyObjectName.hasStock();
Hope it is useful for your and solves your problem .
Related
I'm trying to structure my Nodejs project by component, following this Nodejs best practice repo.
So my question is, how can i place an Order and update the Product items left in db. Should i use ProductsService inside Order component.
Have anyone already implemented this approach? Can you give me some example.
Thank you!
If ProductsService contains a method or function that is exported, you should use this exported function inside of the Order component to update the products in the database.
Example
mymodule.js
// exported function
const myFunction = function(foo) {
if(foo) {
return bar;
}
}
module.exports = myFunction;
index.js
const myModule = require('./mymodule.js');
// using the function
myModule(value);
I have multiple different files broken out like so:
index.js
utils.js
ClassA/
index.js
base.js
utils contains a number of utility functions used everywhere. ClassA/index.js contains the constructor for ClassA as well as requires base.js, then exports ClassA. Base.js exports prototype methods for ClassA. Here is basically what they look like:
//ClassA/index.js
function ClassA () {
//constructor stuff
}
ClassA.prototype.constructor = ClassA;
require('./base')(ClassA);
module.exports = ClassA;
//ClassA/base.js
module.exports = ClassA => {
ClassA.prototype.aMethod = function () {
log('hello');
}
//utils.js
module.exports = {
log : function (logText) {
//dostuff
}
}
So my problem is that I cannot access the log function from within methods in ClassA/base.js. If I set const log = require('../utils').log at the top of the file, it doesn't work. It also doesn't work if I place that same line of code within the exports but outside of the method definitions, however it does work if I place it within the method itself (as expected, but this would mean replicating every require statement in any method in which it's needed). Is there any way around using this messy and repetitive route?
It was an issue with cyclic dependencies. I changed 'log' to be a method of ClassA and this resolved the issue. Thanks to Francois P. for pointing me in the right direction.
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.
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 ..
maybe this question is a little silly, but is it possible to load multiple .js files with one require statement? like this:
var mylib = require('./lib/mylibfiles');
and use:
mylib.foo(); //return "hello from one"
mylib.bar(): //return "hello from two"
And in the folder mylibfiles will have two files:
One.js
exports.foo= function(){return "hello from one";}
Two.js
exports.bar= function(){return "hello from two";}
I was thinking to put a package.json in the folder that say to load all the files, but I don't know how. Other aproach that I was thinking is to have a index.js that exports everything again but I will be duplicating work.
Thanks!!
P.D: I'm working with nodejs v0.611 on a windows 7 machine
First of all using require does not duplicate anything. It loads the module and it caches it, so calling require again will get it from memory (thus you can modify module at fly without interacting with its source code - this is sometimes desirable, for example when you want to store db connection inside module).
Also package.json does not load anything and does not interact with your app at all. It is only used for npm.
Now you cannot require multiple modules at once. For example what will happen if both One.js and Two.js have defined function with the same name?? There are more problems.
But what you can do, is to write additional file, say modules.js with the following content
module.exports = {
one : require('./one.js'),
two : require('./two.js'),
/* some other modules you want */
}
and then you can simply use
var modules = require('./modules.js');
modules.one.foo();
modules.two.bar();
I have a snippet of code that requires more than one module, but it doesn't clump them together as your post suggests. However, that can be overcome with a trick that I found.
function requireMany () {
return Array.prototype.slice.call(arguments).map(function (value) {
try {
return require(value)
}
catch (event) {
return console.log(event)
}
})
}
And you use it as such
requireMany("fs", "socket.io", "path")
Which will return
[ fs {}, socketio {}, path {} ]
If a module is not found, an error will be sent to the console. It won't break the programme. The error will be shown in the array as undefined. The array will not be shorter because one of the modules failed to load.
Then you can bind those each of those array elements to a variable name, like so:
var [fs, socketio, path] = requireMany("fs", "socket.io", "path")
It essentially works like an object, but assigns the keys and their values to the global namespace. So, in your case, you could do:
var [foo, bar] = requireMany("./foo.js", "./bar.js")
foo() //return "hello from one"
bar() //return "hello from two"
And if you do want it to break the programme on error, just use this modified version, which is smaller
function requireMany () {
return Array.prototype.slice.call(arguments).map(require)
}
Yes, you may require a folder as a module, according to the node docs. Let's say you want to require() a folder called ./mypack/.
Inside ./mypack/, create a package.json file with the name of the folder and a main javascript file with the same name, inside a ./lib/ directory.
{
"name" : "mypack",
"main" : "./lib/mypack.js"
}
Now you can use require('./mypack') and node will load ./mypack/lib/mypack.js.
However if you do not include this package.json file, it may still work. Without the file, node will attempt to load ./mypack/index.js, or if that's not there, ./mypack/index.node.
My understanding is that this could be beneficial if you have split your program into many javascript files but do not want to concatenate them for deployment.
You can use destructuring assignment to map an array of exported modules from require statements in one line:
const requires = (...modules) => modules.map(module => require(module));
const [fs, path] = requires('fs', 'path');
I was doing something similar to what #freakish suggests in his answer with a project where I've a list of test scripts that are pulled into a Puppeteer + Jest testing setup. My test files follow the naming convention testname1.js - testnameN.js and I was able use a generator function to require N number of files from the particular directory with the approach below:
const fs = require('fs');
const path = require('path');
module.exports = class FilesInDirectory {
constructor(directory) {
this.fid = fs.readdirSync(path.resolve(directory));
this.requiredFiles = (this.fid.map((fileId) => {
let resolvedPath = path.resolve(directory, fileId);
return require(resolvedPath);
})).filter(file => !!file);
}
printRetrievedFiles() {
console.log(this.requiredFiles);
}
nextFileGenerator() {
const parent = this;
const fidLength = parent.requiredFiles.length;
function* iterate(index) {
while (index < fidLength) {
yield parent.requiredFiles[index++];
}
}
return iterate(0);
}
}
Then use like so:
//Use in test
const FilesInDirectory = require('./utilities/getfilesindirectory');
const StepsCollection = new FilesInDirectory('./test-steps');
const StepsGenerator = StepsCollection.nextFileGenerator();
//Assuming we're in an async function
await StepsGenerator.next().value.FUNCTION_REQUIRED_FROM_FILE(someArg);