Cannot import javascript file in Gulpfile - javascript

I try to use function from another Javascript file in my Gulpfile, but cannot make it work so far.
The file I need to access in Gulpfile:
var hello = function(){
console.log('Hello')
}
And the way I require it in my Gulpfile:
var tools = require('./public/js/tools.js');
gulp.task('create_subscriptions', function(){
tools.hello();
});
tools.hello() is not a function is triggered.
What do I do wrong here?
Edit
I did
module.exports = {
hello: hello()
};
Whats the difference wit exports.hello = hello?

You didn't export anything from your module. Local variables are not exposed, you need to explicitly mark them as public.
exports.hello = hello;
hello: hello()
You have () after the variable holding the function. You are calling it and assigning the return value (which is not a function) to your hello property.

Related

Is there a way to create a global object in JavaScript across files?

I'm back again. I had a thought about some code that I would like to split up between multiple files and such. With that, I need an object declared that tracks all stuff, like arrays, counting variables, and that stuff that I need to access and edit across the project.
So, I have a file where I declare all sorts of objects. Let's call this file Constants.js in the tree;
Main.js
Constants.js
Secondary.js
I'm declaring an object in Constants.js, then I'm requiring that object in the main file. After that, I need to run a function where that's in Secondary.js using the global object and edit it in there. The problem is, if I declare it in the secondary file and edit it, it wouldn't be the same (or updated) in the Main.js file, would it?
Ok so, I have my Constants.js file laid out like the following -
// Constants.js
exports.Tools = {
Stack: [],
Test: "foo",
Track: 0
// ...
};
In the Main.js I'm requiring that object using the following code, and editing what's inside it -
// Main.js
const Constants = require("./Constants.js");
const Tools = Constants.Tools;
Tools.Stack.push("Some stuff");
After that, I'd like to run a function, like so -
// Main.js
require("./Secondary.js").run(Tools);
Then after the function has ran, the Tools object needs to be updated what the Secondary.js:run() did to it. For instance -
// Secondary.js
exports.run = function (Tools) {
Tools.Test = "bar";
Tools.Track++;
}
And so, I'd like the object in the main file to be updated with the new values that Secondary.js did to it.
Is there any way possible for this to happen without using functions in that object or maps? I'd like it to be a normal object.
Thank you very much.
~Q
Declare global variable in main file
Main.js
global.Tools = {
Stack: [],
Test: "foo",
Track: 0
// ...
};
In Secondary.js Just use that variables as
global.Tools.Stack.push(value)
In Node.js global objects are available in all modules, It can be used directly,
No need to import any file.
Ok, I have been doing some digging, and the following example works -
// Constants.js
exports.Tools = {
Test: "foo",
Stack: []
};
// Secondary.js
exports.run = function (Tools) {
Tools.Test = "bar";
Tools.Stack.push("Second");
}
And lastly, the main file that gets ran -
// Main.js
const Constants = require("./Constants.js");
const Tools = Constants.Tools;
Tools.Stack.push("First");
require("./Secondary.js").run(Tools);
console.log(Tools);
/*
Outputs:
{
Test: "bar";
Stack: ['First', 'Second']
}
*/
So, the main file's object does get updated when it's passed through the function. It doesn't also matter if you return that object in the Secondary's function.
And also when you do not pass it through a function, it gets ran successfully like so -
// Secondary.js
exports.run = function () {
const Tools = require("./Constants.js").Tools;
Tools.Test = "bar";
Tools.Stack.push("Second");
}
I hope I helped anyone who had this question.
~Q

module.exports not working as expected

I would like to export one function in node and call it in another file. Somehow it is always executing the whole code in the exporting module (not only the function exported).
//file: test.js
module.exports = function () {
console.log("Hello");
}
console.log("Hello2");
//file: test2.js
var test = require("./test");
test();
// Desired Output: Hello
// My actual Output: Hello2 Hello
Can somebody please explain, why it is also running the second log (Hello2) although this log is not within the exported brackets?
When you require a file, you import the entire file and it gets executed. Since console.log('Hello2'); isn't defined in a function, it gets executed when the file is required.
This is why you should see Hello2 first. And then you call the test function which executes and prints out Hello.
Your output should be:
Hello2
Hello
Try to do a named export,
for example:
module.exports = function first () {
console.log("Hello");
}
and in your test2.js:
var test = require("./test");
test.first();
When you do var test = require("./test"); you are requiring the whole file, rather than just the module you exported. In the file where you wish to use the function, you need to import the function from the other file.
Try doing this:
//file: test.js
module.exports = function () {
console.log("Hello");
}
console.log("Hello2");
//file: test2.js
import { test } from './test'
test();

browserify circular dependency: something is not a function

I've recently started writing CommonJS modules but facing issues in requiring modules. Why is storage.js unable to reach the example module which I have required? What is the proper way to require a dependent module in this case?
EDIT: Included more information because the previous question omitted hello.js, which I thought wasn't the cause of the problem. Seems like including it causes a uncaught type error. Also, this is part of the code for a chrome extension, and main.js is the content script.
// main.js
var hello = require('./hello');
var storage = require('./storage');
var example = require('./example');
storage.store();
// storage.js
var example = require('./example');
module.exports = (function() {
function store() {example.ex();}
return {store: store};
})();
// example.js
var storage = require('./storage');
module.exports = (function() {
function ex() {
console.log('example');
}
return {ex: ex};
})();
// hello.js
var example = require('./example'); // <<<< Including this gives Uncaught TypeError: example.ex is not a function
module.exports = (function() {
function hello() {
console.log('hello');
}
return {hello:hello};
})();
Not a direct answer to your question, but Browserify will wrap in a self-invoking function for you. You can simplify your lib files:
// main.js
var storage = require('./storage');
storage.store();
Because you don't use hello or example, don't require them.
// storage.js
var example = require('./example');
function store() {example.ex();}
module.exports.store = store;
No need to go through the self-invoking function here.
// example.js
module.exports.ex = ex;
function ex() {
console.log('Example');
}
This doesn't use storage, so don't include it.
hello.js does nothing but trigger the circular dependency, remove it.
In your updated code, you have a circular dependency between storage.js and example.js. Because you don't use anything from storage in example, you can just remove that require. I still think you should remove the self-invoking functions, as that's already part of commonjs.
When loading a module, Commonjs will only execute the file a single time. Everything on module.exports is then cached for future calls. When you include the circular dependency for the first time, the module loader sees that its currently being loaded, and you don't get any results back. Subsequent calls will complete as normal.

javascript: call function declared in a different .js file?

I am writing some logic in fileB.js that needs to call another function declared in fileA.js. fileA.js declares a function called abc(). How can I call abc() from fileB.js.
Both fileA and fileB are in the same directory.
Thank you
Ps. I am not using this with HTML. I am just running it locally as part of another project I am working on. I am now using node to run it from terminal. But I am not using anything else in these two files. I just have a bunch of really simple functions. No node.js modules or anything...
Node.js isolates each file as a module, giving each their own local scope to define essentially "private" functions and vars.
With this isolation, fileA will need to export abc in order to share it with other files/modules:
function abc() {
// ...
}
exports.abc = abc;
Then, fileB can require() fileA with a relative path (. referring to the current directory) and use its exported function:
var a = require('./fileA');
a.abc();
If you are using node, then in fileA:
module.exports = { abc: abc } //assuming that abc holds a reference to your function, declared somewhere above
Then, in fileB you require fileA and use what you exported:
var fileA = require('./fileA.js');
fileA.abc();
Since you're running it in NodeJS, I'd suggest doing the following at the top of fileB.js:
var fileA = require( './fileA.js' );
However, in order for this to work, the functions you want to use in fileB.js should be exported from fileA.js. To do this, lets assume that the function abc() is what you want to access:
// In fileA.js:
function abc() {
// ... do something ...
}
module.exports = abc;
If you want multiple functions/variables/objects available to fileB.js, you can export them all as one object:
// In fileA.js
function abc() {
// ... do something here ...
}
var myObject = {
propOne: 'foo',
propTwo: 'bar
};
module.exports = {
abc: abc,
myObject: myObject
};
Then, within fileB.js:
// Import the fileA object you just created.
var fileA = require( './fileA.js' );
// Save references to abc and myObject
var myObject = fileA.myObject,
abc = fileA.abc;
Just include both the JS files in the HTML and then simply call them any function anywhere, it will work.

Require a module as if its module is the module you are requiring it from

I'd like require a module and somehow pass in the current module, or something like that, such that the module being required has the properties of the module requiring it.
For example if I have a file I'm requiring:
(function(global) {
console.log(this.exists);
}(this));
And am requiring it like so:
this.exists = "I exist.";
var myFile = require("my-file"); // Somehow make require pass in 'this'.
The file being required should be able to see this.exists since I've passed this into the require function somehow. I'm not sure if this is possible. I would think you would need to fiddle with the different module objects.
The one constraint of this is that the module being required can't have any nodejs specific things, like code to export it on the module. It has to stay the same as the way I've written it.
Edit:
Turns out there is no way to do this exactly the way I want to. There have been some awesome suggestions on how to do this in other ways, though.
I had to do something similar to this once... best way I figured out was through a level of indirection.
Part1:
define(function() {
"use strict";
function init() {
console.log("this = " + this);
}
return init;
});
Part2:
var myFileInit = require("my-file");
var myFile = myFileInit.init.call(this);
Edit: Another possibility
Create a wrapper for the original module:
// my-file-wrapper
define(["my-file"], function(myFunc) {
"use strict";
function init() {
myFunc.call(this);
}
return init;
});
// Elsewhere
var myFileWrapper = require("my-file-wrapper");
var myFile = myFileInit.init.call(this);

Categories