I am trying to use module.exports() to create a new module in my NW.js application.
I have two files that I am using:
Index.js
const gkm = require('gkm'); //This is a key listener
const AudioStreamMeter = require('audio-stream-meter'); //This is a mic listener
const exportable = require("./twitchAuth.js");
exportable.test();
// More code under this
twitchAuth.js
function doSomething() {
document.getElementById("volume").style.backgroundColor = "#FFF";
}
module.exports(doSomething);
only thing is that when I add const exportable = require("./separateFile.js"); to index.js then gkm and audio-stream-meter stop working as well as the rest of my code.
View the full source code here
I created a PR to fix a bunch of stuff in the repo:
https://github.com/bomeers/Bird-Brain/pull/1
the main issue here though is that module.exports is not a function, it would be assigned an object, such as:
module.exports = { doSomething };
And your paths for importing aren't relative to the CWD
const exportable = require("../app/twitchAuth.js");
Related
I want to create an object that would import functions from another folder and it would look something like this:
class = {
functions: {
//All functions here
}
}
The functions would be inside of a different folder, however, I want to make some sort of importer in which it would make new classes for each new function/file it finds inside of the folder.
someFunction.js Function File:
function someFunction() {
console.log("this is some function");
}
So I would like for something to look like this:
class.functions.someFunction()
No, I do not want to have it hard coded into the object, I want to import all functions from a folder and create functions like that.
Well, first I wan't to answer your question as I think you want, even if I also think it is not the correct way to proceed.
I'll also assume that with class you are not referring to an actual ES6 Class, but we are talking about a plain object.
So this is the code:
const fs = require('fs');
const path = require('path');
function importer(dirPath) {
const absoluteDirPath = path.normalize(
path.isAbsolute(dirPath)
? dirPath
: path.resolve(process.cwd(), dirPath)
);
const output = {
functions: {}
};
const content = fs.readdirSync(path.normalize(absoluteDirPath));
content.forEach((basename) => {
const absoluteItemPath = path.join(absoluteDirPath, basename);
if (fs.statSync(absoluteItemPath).isFile() && /\.js$/i.test(basename)) {
output.functions[basename.slice(-3)] = require(path.relative(
__dirname,
absoluteItemPath
));
}
});
return output;
}
module.exports = importer;
For this to work, all your functions in your files should be exported like:
module.exports = function myFunction() {};
To use the 'importer', you just do:
const artemis = importer('/path/to/directory'); // PATH MUST BE ABSOLUTE OR RELATIVE TO CWD.
/*
SUPPOSING THAT YOUR DIRECTORY CONTAINS THE FOLLOWING FILES:
function1.js
function2.js
Then you can do:
artemis.function1();
artemis.function2();
Please note that your files must be named in a JS friendly way (a valid string for an object key).
*/
A final important note about this odd method: This will only ever work in a NodeJS environment. Even if functions could have worked in other environments (like a browser). The next method, will work for any ECMAScript environment after proper building process: transpilation (EX: Babel) and bundling (EX: Webpack).
Suggested Solution
Use ES6 Static import / export like modern JS libraries do. This comes with huge benefits, from static code analysis to tree shaking and more.
Let's suppose the following hierarchy:
// - index.js
// - internals/
// - index.js
// - module-1.js
// - module-2.js
internals/module-1.js
function module1() {}
export {module1};
internals/module-2.js
import {module1} from 'module-1.js';
function module2() {
// YOU CAN USE module1 IF YOU NEED. (AVOID CIRCULAR REFERENCES)
module1();
}
export {module2};
internals/index.js
import {module1} from './module-1.js';
import {module2} from './module-2.js';
export {module1, module2};
index.js
import * as moduleGroup from './internals/index.js';
export {moduleGroup};
Finally, where you import your moduleGroup, you can do:
moduleGroup.module1();
moduleGroup.module2();
Obviously this is a basic scenario, but this is, IMHO, the correct way to deliver a group of functions and other stuff. Please let me know if you have any doubt.
I m creating an api.
Soo my API Structure is like
<myapi_folder>
|
---index.js
---package.json
---<utils_folder>
|
---load.js
Now let work.js is a file which is located somewhere on my system.
The code of
work.js
const myapp = require("myapi_folder");
The point is i want to know the directory location of work.js in load.js program.
Please help me.
Thanks in advance
How does work.js interact with load.js? I assume that worker.js require 'myapi_folder', and 'myapi_folder/index.js' called 'load.js'?
There are two possible ways.
1 - Explicitly pass __dirname of caller to callee. In your case:
// myapi_folder/index.js
function load(callerDir) {
require('./load').do(callerDir);
}
// worker.js
var api = require('myapi_folder');
api.load(__dirname);
2- Use callsite, this is hacky and not recommended for this case.
// myapi_folder/index.js
var callsite = require('callsite');
function load() {
var callerDir = callsite()[1].getFileName();
require('./load').do(callerDir);
}
We use the approot module and it works very well.
This is at the top of most of our node modules:
var appRoot = require('app-root-path');
var logger = require(appRoot + '/services/logger');
var cache = require(appRoot + '/services/cache');
I am working on an existing node project where the code structure for most of the js files looks something like following.
var mod1 = require("mod1");
var mod2 = require("mod2");
var modn = require("moden");
function func1(data, callback) {
// Do some validation with data etc..
// Use one or more imported modules here
}
function func2(data, callback) {
// Do some validation with data etc..
// Use one or more imported modules here
}
exports.func1 = func1
exports.func2 = func2
How can unit test func1, while not being dependent on the imported modules? How can I mock/stub them?
I come from the Java world so I am familiar with the mocking concepts, but here I am not sure how can I mock the globally declared module imports using require.
Currently we are using nodeunit for the unit testing purpose, but it tests very small part of the code.
I am reading about simon.js and testdouble but not sure how to use them to mock the global variables.
Any help/direction is appreciated.
For overriding dependencies during testing I recommend to use in your situation the https://github.com/thlorenz/proxyquire module
For quick exmple I paste example from project github
foo.js:
var path = require('path');
module.exports.extnameAllCaps = function (file) {
return path.extname(file).toUpperCase();
};
module.exports.basenameAllCaps = function (file) {
return path.basename(file).toUpperCase();
}
foo.test.js:
var proxyquire = require('proxyquire')
, assert = require('assert')
, pathStub = { };
// when no overrides are specified, path.extname behaves normally
var foo = proxyquire('./foo', { 'path': pathStub });
assert.equal(foo.extnameAllCaps('file.txt'), '.TXT');
I have two js files in Electron (which uses Nodejs) and I try to export from one and require in another.
app.js:
App = {
server: {
host: '192.168.0.5',
user: 'root',
}
ping: function() {
}
}
exports.App = App
I have tried every way possible of exporting, including module.exports = App, module.exports.App = App and so on.
ping.js first attempt:
var App = require('../app.js') // I have also tried adding .App to the end
console.log(App) // This returns an object which contains the App object
ping.js second attempt:
var App = require('../app.js')
App.x = 'y'
console.log(App) // this returns an object which contains the App object and the x property
It may appear that App contains another App object, but console.log(App.App) says it doesn't exist.
The first thing I'd to do solve this would be to make sure I'm using the full path to the required module, as in:
const Path = require('path')
const App = require(Path.join(__dirname,'../app')) // the .js isn't needed here.
Note that this assumes that the app.js file is in the immediate parent directory of the one in which the application runs.
If that doesn't work, I'd make sure the files are where you think they are, and that the process you're running is located within the file system where you think it is. You can determine this by adding this to the top of your main script file:
console.log("current working directory:",process.cwd())
Or in es6:
console.log(`current working directory: %s`, process.cwd())
If the printed directory doesn't match your assumptions, modify your require statement accordingly.
And for the record, the "correct" way to export your App map would be to:
const App = {
...
}
module.exports = App
Or using es7:
export default App = {
...
}
(See export for more on es7 modules.)
Either way, you'd then require the module as:
const App = require(PATH_TO_APP)
I have a file fetching some other files:
start.js
require("./users");
but the users.js file is not in the current folder but in model/.
I want to be able to run:
node start.js model
and it would assume that ./ is the same as model/ in start.js.
How do I do that?
All you need to do is to make Node.js recognize the folder model as a module.
In order to do that, you need to place a file called index.js inside the model folder.
// model/index.js
exports.users = require('./users'); // model/users.js
exports.posts = require('./posts'); // model/posts.js
// etc.
Now you can import the model module and access it's exports:
var models = require('./model');
models.users.create(); // some function exported in model/users.js
models.posts.list(); // this was exported in model/posts.js
You can add ./model dir to require.paths array:
require.paths.unshift("./model");
var
users = require("users"), // It works!
posts = require("posts");
But I want to ask you: why do you need this instead of using
var
users = require("./model/users"), // It works!
posts = require("./model/posts");
?