about node.js / javascript sharing variable between file - javascript

I have some files that need database access so I have a file like this:
...
var dynamo = new AWS.DynamoDB.DocumentClient();
module.exports.getDatabase= function(){
return dynamo;
};
...
I wonder if different .js files use it like this:
var DataUtil = require('./shared/dataUtils.js');
...
var database = DataUtil.getDatabase();
....
are they using the same instance of the object? or just instantiating a copy for each of the .js file using the requiring?

Yes, it's the same instance. When you require a module, it's only loaded when it's not already loaded. So there's only one instance of a module in a node program.
From the documentation:
Modules are cached after the first time they are loaded. This means
(among other things) that every call to require('foo') will get
exactly the same object returned, if it would resolve to the same
file.
In your case, you'll have only one instance of AWS.DynamoDB.DocumentClient.

Related

node.js dynamic module(file) export

how can I exports this dynamic module?
// ./data/example5.js
module.exports = {title : example5, recentCheck : "2018-08-22"}
The contents change in real time. And I execute the followed function once a minute and connect the module.
var files = fs.readdirSync(`./data/`);
var i = 0;
var link = [];
while(i<files.length){ // read all file
link[i] = require(`../data/${files[i]}`);
 
//main.js
setInterval(start,10000);
I try to create and connect a new module file once a minute, but the first stored file(module) is extracted. The modulefile is being saved in real time correctly.
Shutting down and running the node will extract the changed modules correctly.
How do I handle a dynamically changing module?
I would recommend saving the data in a JSON file and then reading the data from the file rather than trying to use it as a module.
Just make the objects you're updating variables in the module that you're including.
Make a function called getVariable, and simply return the variable.
Include getVariable in your main module.

Require module in Node JS

I used Node JS for web application development. I have a confusion in require() module. I am requiring a JS file located in file_handler directory.
What is the difference between both of the following?
// in server.js
var chat = require("./file_handler/chat.js"); // Does not work
OR
var chat = require("./file_handler/chat.js")(); // It works
Why is the extra parenthesis in the last of the statement?
In the first line the exported function is assigned to chat variable so then you can call it like next like chat();
In the second one the return of exported function is returned to chat variable.
It is actually based on what you export in your module. If you export the object you need, you can just directly do require('module'). If you export a function which returns the object you need, you have to execute that exported function require('module')() to get the desired object.
Read the documentation https://nodejs.org/api/modules.html

How to access a variable declared in yepnope.js from loaded JavaScript file?

I have a yepnope.js file which loads several other JavaScript files.
In yepnope.js I have a variable called applicationVersion, which I append to the end of load url like this: load: 'fileToLoad.js?v=' + applicationVersion to enable cache busting!
Now I need to be able to access this applicationVersion from fileToLoad.js to enable cache busting for other functions within fileToLoad.js. Can I just access the variable from fileToLoad.js like the following?
//in fileToLoad.js
var ajaxUrl = '/json/messages?v=' + applicationVersion;
Or do I need other mechanisms to somehow pass the variable down from yepnope.js to fileToLoad.js?
I am not in an environment where I can test this out.
You can pass the applicationVersion with using a namespacing a variable.Hope this following snippet will help
Assuming this is your yepnope.js
var myYepnope = myYepnope || {} //Defining namespace;
myYepnope.applicationVersion:"someVesrion";
myYepnope.loader =function(){
// code related to yepnope file loader
}
myYepnome.loader() // to execute the function
Now applicationVersion will be accessible from fileToLoad.js by calling myYepnope.applicationVersion
A change in value of myYepnope.applicationVersion will be reflected everywhere

Requiring Singleton Instances in Node

I spied in some code the following:
var Log = require('log');
// This creates a singleton instance
module.exports = new Log('info');
My first reaction was "no way that is a singleton", but I remember an article that outlined how Node.js does require() statements said something about caching require statements and using them in subsequent calls.
So basically my question, is exporting a new Object() actually creating a singleton behind the scenes?
I know there are other ways of creating singletons in JavaScript, but this seems like a pretty handy way of doing it inside Node (if it actually works).
Yes, that's the closest thing to a Singleton in Node.js. require() caches each module upon the first invocation, so every subsequent require() returns always the same instance.
However you must be aware that this is not always enforced. The cache could be modified/removed, also the module is cached using its fullpath, in short it means that if you define a singleton in a package and your package is installed as nested dependency, you may have several instances of your "singleton" within the context of the same application.
Quick example:
Application
node_modules
PackageA
node_modules
YourPackageWithSingleton
PackageB
node_modules
YourPackageWithSingleton
Usually you don't have to worry about this, but if you really need to share one object across the entire application, the only solution is using globals (discouraged) or Dependency Injection.
Its not really a singleton due to you could create as much instances of Log as you want. But you can use it like this. Otherwise you just can create an plain object by var mySingleton = {} and attach attributes and methods to it.
Then you can assign mySingleton to module.exports and require() it in other modules.
foo.js:
var mySingleton = {
someMethod = function () {}
};
module.exports = mySingleton;
bar.js:
var singletonClass = require('./foo.js');
singletonClass.someMethod();
Why not test it out for yourself?
$ cat test.js
module.exports = Math.random();
$ node
> var a = require("./test");
undefined
> var a = require("./test");
undefined
> a === b
true
Yes, it seems that node.js does indeed cache exported values. Hence if you require the same module again it will return the cached value instead of creating a new value.
It should be noted however that the programmer could just require("log") and create a new instance manually. So in that sense it is not a singleton.

Multiple Javascript files, I want to take out URL constants into a seperate file

As the title says, I have a few javascript files. There are sections that call a few websites. I want to be able to store the websites in a different file, this way if the website changes we just need to make one change and not many.
Any suggestions?
I tried doing something like
/**
* Returns URLs
*/
var URLCONTEXT = "/root-url/context/";
var URLROOT = "/root-url/";
function getContextUrl(){
return URLCONTEXT;
}
function getRootUrl(){
return URLROOT;
}
but this doesn't have a way to communicate with the other JS files =/
Include your url constants in a js file like
url-constants.js
var URLCONTEXT = "/root-url/context/";
var URLROOT = "/root-url/";
and reference this js file first before other js files.
and you will be able to use url-constants variable in any other js file.
other.js
function getContextUrl(){
return URLCONTEXT;
}
function getRootUrl(){
return URLROOT;
}
include these in your page like
<script language="text/javascript" src="url-constants.js"></script>
<script language="text/javascript" src="other.js"></script>
var's defined outside of a function, and functions defined with a name are in the global namespace. You can access them from your other JS files as long as this JS file is loaded first.
You should be able to do that. Just make sure the file with the urls is included before the files where it's accessed from.
Also, I would not recommend polluting the global scope with these, even if you named them in capital letters. How about defining
var URLS = {
urlContext: '/root-url/context',
urlRoot: '/root-url'
};
and using them in other files with URLS.urlContext and URLS.urlRoot?

Categories

Resources