Can see function from javascript file but not variables - javascript

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..

Related

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

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();

What will happen after bundling 2 .js files which have a function with same name and Parameter using bundle.config?

If two .js files having functions with the same name and parameter but the code is different. What will happen after bundling using bundle.config?
Which one will call?
Or/And how can we fix that?
//in parent.js file
function getdetails(id)
{
//enter code here
}
//in student.js file
function getdetails(id)
{
//enter code here
}
Depending on the type of bundler, normally functions are scoped from the modules they are exported from.
So for example:
//in parent.js file
function getdetails(id)
{
//enter code here
}
//in student.js file
function getdetails(id)
{
//enter code here
}
In the bundled javascript, they become (as an general example):
_parent.getdetails()
_student.getdetails()
You could check your un-minified bundled code and search for getdetails to see how the functions are being scoped for clarification.
Side note
If two functions are being defined with the same name, in the same scope (which shouldn't be the case here), then the function re-defined each time.
//in parent.js file
function getdetails() {console.log("foo");}
function getdetails() {console.log("bar");}
getdetails(); // Outputs "bar"

Does Node run all the code inside required modules?

Are node modules run when they are required?
For example: You have a file foo.js that contains some code and some exports.
When I import the file by running the following code
var foo = require(./foo.js);
is all the code inside the file foo.js run and only exported after that?
Much like in a browser's <script>, as soon as you require a module the code is parsed and executed.
However, depending on how the module's code is structured, there may be no function calls.
For example:
// my-module-1.js
// This one only defines a function.
// Nothing happens until you call it.
function doSomething () {
// body
}
module.exports = doSomething;
// my-module-2.js
// This one will actually call the anonymous
// function as soon as you `require` it.
(function () {
// body
})();
Some examples..
'use strict';
var a = 2 * 4; //this is executed when require called
console.log('required'); //so is this..
function doSomething() {}; //this is just parsed
module.exports = doSomething; //this is placed on the exports, but still not executed..
Only in the sense that any other JS code is run when loaded.
e.g. a function definition in the main body of the module will be run and create a function, but that function won't be called until some other code actually calls it.
Before exporting the content that are visible outside of your module, if there is same code that can be execute it it execute but the content that are export like a class will be execute in the code that import it.
For example, if I have this code
console.log("foo.js")
module.exports = {
Person: function(){}
}
the console.log will be execute when you require it.

Using a RequireJS module more than once does not run

Running require(['pages/home']) will work once but if I use require(['pages/home']) again then it won't run.
The module "pages/home" is a file named "home.js" in a directory named "pages".
main.js
require(['pages/home']);
pages/home.js
define('pages/home', function() {
console.log('running pages/home module');
});
RequireJS modules are singletons. It loads a module once and only once. If a module has been loaded already, what you get if you load it again is a reference to the same module as originally loaded. The factory function you pass to define won't be run a second time.
So what you are seeing is exactly what is expected.
Static code in modules isn't supposed to be evaluated more than once, just like a script loaded through a normal <script> tag won't be run more than once during the page load.
Imagine if a module contained code like:
define('my-module', function () {
var foo = foo || 0;
var bar = ++foo;
});
You should expect bar and foo to both === 1, but if the module was run repeatedly and a global foo existed, that may not be the case. Admittedly, this is a very contrived example, but evaluating a module repeatedly could cause serious problems.
Make it return a function/object that can be executed after you require it.
define('pages/home', function() {
return function(){
console.log('running pages/home module');
};
});
require(['pages/home'], function(resultFunc){
window.YourFunc = resultFunc;
});
Now you can execute your function whenever you want

How to use function declared in different JS file using jQuery getScript?

I have two JS files. One is called common.js and it use $.getScript to include other file with my js code. Part of including looks like this:
jQuery.getScript(js_path + "table.js", function(){
generateTable(chartData, dataTypes);
});
This file (common.js) also contains function compare(a, b).
Now, the second one (table.js) has declared different function which uses the compare function from the first file. Something like this:
function someName() {
var a = 2,
b = 5;
var test = compare(a, b);
return test;
}
When I run the code it gives me:
Uncaught ReferenceError: compare is not defined
How can I use function from the first file.
jQuery.getScript first fetches the JS file from the server, then executes it. If you want to work with global functions (as it seems) you need to pay attention to the following:
Your compare function must be declared before the table.js file is executed.
The compare function must be declared on the global namespace of table.js.
Sorry but without more info this is all you can get.
If your main file, as something like:
(function() {
function compare(){...}
}());
Then the compare function is not declared in the global namespace.
did you check the order of imports? The file with 'compare' method should be first. It should solve the problem.
What I would suggest is to skip getScript if it's just for separating the code.
<script src="common.js"></script>
<script src="table.js"></script>
<script src="app.js"></script>
Where common functions go into common, your table stuff goes into table. This way you get the ordering right. This also clears out the circular dependency one might see a hint of if table depends on common that depends on table by extracting all but the 'common' parts into some form of 'app'.

Categories

Resources