How do I name an imported module dynamically with javascript eval()? - javascript

I want to create a dynamically named variable so that I can use it as a module. I am using eval() to do it, but for some reason it's not working as expected and claiming that the constant I created inside of it doesn't exist.
I have a main folder with this structure:
main
|- commands
|- |- testmod.js
|- test.js
Testmod.js has a simple function export inside of it that logs something to console when run:
function cmd() {
console.log('it worked :)');
}
module.exports = { cmd };
And in test.js, I want to try importing it dynamically:
const foo = 'testmodule';
eval(`const ${foo} = require('./commands/testmod.js');`);
eval(`${foo}.cmd();`)
However, it runs with an error, ReferenceError: testmodule is not defined, and I don't know why.
Expected:
1. define a variable named foo
2. evaluate a string that requires contents of another js file, and name that import as the contents of variable foo
3. evaluate this: a module with name of variable foo and then run the command 'cmd()' inside of it.
expected output: it worked :)
Should I try to find a different method of dynamically naming variables? I'm 99% sure that this method of doing things is unstable and unintended, but if I could get it to work somehow it would be great.

Alright, so my solution was to create an Object, then assign stuff to it. This way, there aren't any new variables and its just an object that can be called later. Thanks Emiel.
const foo = 'testmodule';
let bar = {
foo: require('./commands/testmod.js'),
};
bar.foo.cmd();

Related

Foreign variables display as 'undefined'

Hello to anyone who will read this post,
I have two standalone javascript files, one of which possesses a class with variables that I would like to use in the other file. We will call the file that possesses the class script.js, and the other file index.js. The code inside index (which is the main file we want to run) compiles fine, but when I run it, my variable prints out as 'undefined'. The variables work fine when they are inside index file themselves, but inside the script.js's class, they are undefined. I would very much like to keep script.js, and keep my variables inside the class. I use an object instance that we will call script obj, and I would very much like to keep my objects. I am not a fan of the static method.
Example: Script.js's class
class script{
constructor(){
var laggies = parseInt(1)
}
}
Above, laggies is defined with a value of 1. Nice, yes? Now let us look at index.js(Just pretend that the object has been initialized)
Example:
console.log(obj.laggies)
This is where I get my problem. I am using repl.it with node version 12.16.1
Thank you for your time.
You are getting the undefined error because the class does not have a variable called laggies. Its defined inside the constructor of the class and not elsewhere.
Try this
class script{
constructor() {
this.laggies = parseInt( 1)
}
}

Using 'export' keyword solely for importing into Unit Tests

I'm using Meteor and am writing unit tests for a Collection. I've got Helper methods for the collection in addition to just regular JS functions.
I.e.
Collection.helpers({
helperFn: function () {
return 'foo';
}
});
//And in the same file
function bar() {
return "bar";
}
Then in my tests file I have something like
import { Collection } from '../collections'
//Use Factory or Stub to create test Document
//This then works just fine and I can assert, etc..
testDoc.helperFn
My question is with wanting to test just the regular 'bar' JS function. This isn't a big deal using ES6 classes because then I can just export the whole class and call any function with an instance of it. But with Meteor I'm finding the only way I can access the function is by using the 'export' keyword.
So in my Collection file
export function bar ({ return bar; });
And now in my test file I'd do something like
import { bar } from '../collection'
I'd rather not add an export statement for every time I test a new function. Is there any way around this or is it not a big deal?
I do think that the export/import is the way to go, but to answer the first part of your question: yes, you can fall back to the original scoping of meteor and put these functions in the global scope of meteor as follows:
do not put your files in the imports/ folder, but into another folder in your project, e.g., server/.
defined the functions as:
bar = function() { /* function body */ }
These variables are interpreted by meteor as being global to the project, and hence do not need to be imported before use.
That said, there was a reason meteor introduced the imports/ folder and corresponding export/import paradigm in version 1.3. It avoids polluting the global scope and makes it much easier to see where things are defined.

Can see function from javascript file but not variables

My directory structure is as follows:
src
|--> js
|--> more js files in nested folders
test
|--> spec
|--> js test files
If within one of my js tests in spec, if I try and call a function from a js file within my nested src directories, I can call the function fine. However, if I try and call a variable, it cannot find it, and I get a Reference Error.
My function (which is visible) is declared like so:
function myFunctionName() {
... some code ...
}
My variable is declared after the function, and not inside any other function, like so:
var myVar = '...';
I've also tried declaring myVar as a const, for the same result.
In myTestSpec.js
(function () {
'use strict';
describe('...', function() {
it('...', function () {
// Works
expect(myFunctionName()).toEqual('...');
// Doesn't work
var newVar = myVar;
});
});
})();
Ended up solving this by just sticking any 'global' state I required into a function, to be returned as json. I now just need to call this function everytime I start a test.
This has a slight performance hit I guess as we need to recreate the state across multiple tests, however it's not production code (test only) so shouldn't be an issue, and it means I don't have to depend on another JS library such as require js..

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

meaning of module.exports= function in node.js

I am taking first steps with node.js and obviously one of the first things i tried to do was exporting some data from a module, so i tried this simple case:
dummy.js:
var user = "rally";
module.exports = {
user:user
};
and than required it from a different file like this:
var dummy = require('./dummy.js');
console.log(dummy.user); // rally
So far so good, every thing works, but now i dived into code where there is this definition in the beginning of the module:
module.exports = function(passport,config, mongoose) {}
and i don't understand whats the meaning of it and how can i work with it.
just for trying to understand i defined some variables inside this abstract function but couldn't get their value from any other file.
any idea how can i export variables from module defined like this..? so for example i could require this module and get the "Dummy" variable and use it in a different file
module.exports = function(passport,config, mongoose) {
var dummy = "Dummy";
}
It works exactly the same as the first one does, only that it exports a function instead of an object.
The module that imports the module can then call that function:
var dummy = require('./dummy.js');
dummy();
any idea how can i export variables from module defined like this..?
Since functions are just objects, you can also assign properties to it:
module.exports = function(passport,config, mongoose) {}
module.exports.user = 'rally';
However I'd argue that this is less expected if a module directly exports a function. You are probably better off exporting the function as its own export:
exports.login = function(passport,config, mongoose) {}
exports.user = 'rally';
WHAT IS A MODULE?
A module encapsulates related code into a single unit of code. When creating a module, this can be interpreted as moving all related functions into a file.
// dummy.js
var exports = module.exports = {};
The utility of dummy.js increases when its encapsulated code can be utilized in other files. This is achieved by using exports.
HOW ARE THEY INVOKED?
You could declare your functions outside of the module.exports block. Functions inside exports can be invoked exactly the same way as variables or any other object.
EXAMPLE
//dummy.js
var myVariable = "foo";
var myFunction = function(){
//some logic
};
module.exports{
myVariable : myVariable,
myFunction : myFunction,
myVariableTypeTwo : "bar",
myFunctionTypeTwo : function () {
//some logic
}
}
We can now access the publicly available methods of dummy.js as a property from any js file.
var dummy = require('./dummy.js');
dummy.myVariable; //foo
dummy.myFunction();
dummy.myVariableTypeTwo; //bar
dummy.myFunctionTypeTwo();
NOTE
In the code above, we could have replaced module.exports with exports and achieved the same result. If this seems confusing, remember that exports and module.exports reference the same object.

Categories

Resources