I have defined a function and put it into a separate file (util.js) in a util folder. I then export the function within the module.
I then require the module in the main function and then invoke the function in the main function.
However the lambda console always prompts that it is unable to find the module "util/util.js"
I have tried everything I can think of and hope that you can help me getting things back on track.
The util.js (placed in a folder named "util":
module.exports.generateText = generateText
function generateText() {
console.log("Function invoked")
}
The main function requiring the util.js and invoking the function:
const referenced = require("util/util.js")
exports.handler = (event, context, callback) => {
// invoke the function in the util.js
referenced.generateText()
}
I just would like to call the function in the util/util.js file from the main function.
To import a local module, you need to prefix the path with "./": const referenced = require("./util/util.js")
Related
I wrote a module to contain some of the less interesting bits of a large Javascript codebase I am working on, call it boring.js.
It is imported from a main module that does most of the more interesting work, call it main.js.
There is a class in boring.js called Log, which is exported to main.js and instantiated to a variable log. Calling the function log.save(newLogMsg) saves newLogMsg to file.
log.save(newLogMsg) works fine when called from main.js
When I try to call log.save(newLogMsg) from inside a function that resides in boring.js, I get the error:
ReferenceError: log is not defined
Which is confusing to me, because let log = new Log is initialized in the main module before I call the function in question (from main.js) that resides inside the imported module.
Side Question: Why can I call console.log(newLogMsg) from any module that I choose? How could I go about implementing a similar functionality for my Log class?
An imported module cannot access the namespace of the module that imports it.
Say you have a module named module.js that looks like this:
// module.js
exports.x = 10;
And a script main.js that imports it:
// main.js
const s = "abc";
const m = require('./module');
Here is what happens when running main.js:
Line 1: the string "abc" is mapped to the name s in the main namespace
Line 2: the require function executes the script named module.js and
returns its export object. The script runs in its own scope and doesn't
know anything about the script which is importing it. Therefore it cannot
see the constant s defined in main.js
Line 2: the return value of require (the module's export object) is
assigned to the constant m defined inside main.js
About your side question:
you could pass the log object as a parameter to a function defined
inside module.js
you can define log in a third module and require it both from main.js and from module.js
I have a file that exports one function that relies on a private one:
function __a(filePath, someFunction){
// do some file request
someFunction(filePath)
}
function b(filePath){
__a(filePath, require)
}
module.exports = {
b: b
}
And I'd like to test that the private function __a toHaveBeenCalledWith some parameters so __a does not actually try and fetch some file I can not assure exists.
I understand the concept that when I'm importing b I am getting a reference to the function and __a just lives within the scope of it, and I can't have access to it so using stuff like:
import appResources from './index';
// ... test
jest.spyOn(applicationResources, '__a').mockImplementationOnce(myParams);
How can I avoid __a excecution here and make sure it's been called?
It's impossible to mock or spy on existing function that isn't used as a method.
__a and b should either reside in different modules, or a should be used as a method within same module. For CommonJS modules there's existing exports object that can be used:
exports.__a = function __a(filePath, someFunction){
// do some file request
someFunction(filePath)
}
exports.b = function b(filePath){
exports.__a(filePath, require)
}
Notice that module.exports isn't replaced, otherwise it won't be possible to refer it as exports.
I recently tried to organize my code by exporting functions into different files, so my main file stays clean. To do so I imported the other js file in my main file with
const request = require('./request.js');
In "request.js" I used export, so I can call the function in my main file. Is it is possible to call a function, that is defined in the main file, from the "request.js" file? Unfortunately I can't just return the information back to the main file, because I am using callbacks.
Yes it's possible.
You just need to export function from the main file and then import your main file inside request.js:
// main.js:
module.exports.someFunction = function() {
// Some code
};
const request = require('./request.js');
request.someRequestFunction();
// request.js
var main = require('./main.js');
module.exports = {
someRequestFunction: function() {
main.someFunction(); // Call function from main module
}
};
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.
I have a node server and I want to add an external .js file (say something.js). I have this code for now:
var st = require('./js/something');
Where something.js is the JavaScript file inside a /js/ folder. The server compiles and run, but when I try to use functions defined in something.js node tells me they are not defined.
I also tried to run them using like st.s() but nothing happens and I have an error saying that the object has no method s().
Can anyone help me?
Thanks,
EDIT:
logging st gives {} (I obtain it from console.log(JSON.stringify(st)). Also doing console.log(st) gives {} as result.
The content of something.js is just a bunch of functions defined like this
function s() {
alert("s");
}
function t() {
alert("t");
}
Node.js uses the CommonJS module format. Essentially values that are attached to the exports object are available to users of the module. So if you are using a module like this
var st = require('./js/something');
st.s();
st.t();
Your module has to export those functions. So you need to attach them to the exports object.
exports.s = function () {
console.log("s");
}
exports.t = function () {
console.log("t");
}