nodejs import file and use functions natively - node.js

How can I import/require a file, and then use the functions in the file natively?
Say I have file 1:
const file2 = require("./file2.js")
const text = "hello"
file2.print()
And in file 2 I have:
module.exports = {
print:()=>{
console.log(text)
}
}
I want to be able to use functions from another file as if they were in the original file, retaining the variables and objects created in the first file, is this possible?

No, the modules are separate, unless you resort to assigning your variables into the global object and hoping that you can keep track of them without going insane. Don't do that.
Either
pass the data you need around (the best option most of the time), or
maybe add a third module containing the shared state you need and require() it from both file 1 and file 2

No!
But
The regular pattern of shared context is that you create a context and share it. The most simple form of it is something like this:
//In file 1 -->
let myContext = {
text: 'hello'
}
file2.print(myContext);
//In file 2 -->
module.exports = {
print:(ctx)=>{
console.log(ctx.text)
}
}
However
JS has some inbuilt support for context. Something like this:
//In file 1 -->
let myContext = {
text: 'hello'
}
let print = file2.print.bind(myContext);
print();
//In file 2 -->
module.exports = {
print: function(){
console.log(this.text)
}
}
Notice the removal of the argument and changing the arrow function to a function expression.

Related

Apply node module with object prototype methods

Good morning.
I'm trying to create a node module witch right now is published as redgem.
It consists of adding methods to base objects prototypes. For example:
const obj = { a: 'b', c: 'd' }
obj.map(do stuff)
However i haven't found a good way to apply these methods in a project. If i run the tests (they are inside the module) they all run smoothly since methods are added to base objects (arrays, strings and actual objects). But if i do the same thing in another project i get errors like Uncaught TypeError: Illegal invocation.
Could anyone please help me setup the package?
The way i'm trying to use redgem in projects right now is:
import redgem from 'redgem';
redgem():
Thanks.
So, basically this is how i export the module:
export default function apply () {
stringMethods.forEach((method) => {
String.prototype[method.name] = method.function
})
arrayMethods.forEach((method) => {
Array.prototype[method.name] = method.function
})
objectMethods.forEach((method) => {
Object.prototype[method.name] = method.function
})
}
Where every method is in the following form
{
// Tells wether the array is empty.
name: 'empty',
function: function () {
return this.length == 0
}
}

Export and Use same function in node js

I have exported a function to set random color, which returns me a random color for every call.
like,
exports.getRandomColor = function(index) {
//return random color
}
If I put function like this I can be able to get access to that function from another file. But not inside the same file. (i.e) This getRandomColor is not get accessed in the same file,
It works good if I use
function getRandomColor(index) {
//return random color
}
The problem is I cannot able to access this on another file. Suggestions are welcome.
Thanks in advance
So you can have the next in your file
// define named function
function getRandomColor(index) {
return random color
}
// assign it to the exports, like below
exports.getRandomColor = getRandomColor
Then you can reuse this function whenever you want.

Test the existence of a dynamically chosen class

I have data coming from an external source that I want to process. In order to do that, the objects I'm receiving are tagged with their original class name. Now I want to take that tag name and use it to populate a model in my own application. I'm stuck at the step where I check for that class having an equivalent in my codebase. Its going to look something like this:
this.objects.forEach((object) => {
if (typeof object.class_tag !== 'undefined') { //the problem line
//create class instance
}
});
In php I'd simply call class_exists to achieve this
<?php
if (class_exists($object->class_tag)) {}
What is the correct approach here?
I don't see the clear way to do this in a just one line.
One of the possible approaches is the way you register your existing classes.
For example if you use some kind of a namespace later on you can simply check the class for existance in the namespace.
Sample code:
class A {}
const a = "A"
const namespace = { A };
if (namespace[a]) {
// class exists, you can create object
const instance = new namespace[a]();
}
Probably, much better approach would be to make some service, that will registerClass, checkClass and createInstance for you. So your logic is wrapped in one place.
I found a way of doing it
(credit to https://stackoverflow.com/a/34656123/746549)
let logger = require('../javascripts/serverlog');
let util = require('util');
let Extension = require('../models/object/Extension');
const classes = {Extension: Extension};
/**
* Utility to emulate class exists / dynamic class naming
* #param className
* #returns {*}
*/
module.exports.dynamicClass = (className) => {
logger.debug(classes);
logger.debug(className);
if (classes[className]) {
return classes[className];
} else {
return false;
}
};
Usage:
let ClassOrFalse = dynamicClass.dynamicClass(object._class_tag);

Does assigning module.exports to a separate object waste memory

There are two basic ways that I see Node modules being written. The first setting each function or variable you want to export to its own property on module.exports:
module.exports.foo = function () {
...
}
And the second is creating a new object that has the properties you want to export, and assigning module.exports to that at the end of the file:
var FooObject = {
foo: function () {
...
}
};
...
module.exports = FooObject;
A third thing that I sometimes see is setting module.exports to an object which has all the properties you want to export, but for the purposes of this discussion, that's equivalent to the first method I mentioned:
module.exports = {
foo: function () {
...
}
}
Are we wasting memory by doing it the second way (creating an object and assigning module.exports to that)? I always thought that since all assignment is a reference, a new object should be created when you do module.exports = {...} so these two would be equivalent. Is that not the case?
The last two examples are equivalent. The only difference is that the second one is setting the object by name and the third is setting it by the object literal.

Multiple Greasemonkey Metablocks

I'm trying to write a Greasemonkey script for a hierarchy of websites such that I have a bunch of code modifications for http://www.foo.com/*, then more specific ones for http://www.foo.com/bar/*, and still others for http://www.foo.com/foobar/*.
Is there anyway for me to write all these in the same script, or do I have to make multiple?
Is there anyway for me to write all
these in the same script, or do I have
to make multiple?
Yes, just use those three #includes, then in your user script do something like (depends on specifics of script):
var currentURL = (document.location+'');
if (currentURL .match(/http:\/\/www\.foo\.com\/foobar\/.*/)) {
// do stuff for page set A
} else if (currentURL .match(/http:\/\/www\.foo\.com\/foo\/.*/)) {
// do stuff for page set B
} else if (currentURL .match(/http:\/\/www\.foo\.com\/.*/)) {
// do stuff for page set C
}
One nifty trick I was shown for dealing with different functions at different sub-locations is to use the global directory of function names as a sort of virtual switchboard...
// do anything that is supposed to apply to the entire website above here.
var place = location.pathname.replace(/\/|\.(php|html)$/gi, "").toLowerCase();
// the regex converts from "foo/" or "foo.php" or "foo.html" to just "foo".
var handler;
if ((handler = global["at_" + place])) {
handler();
}
// end of top-level code. Following is all function definitions:
function at_foo() {
// do foo-based stuff here
}
function at_foobar() {
// do foobar stuff here.
}

Resources