My project structure is the following:
project
- js
- *.js
app.js
In my app.js, I define a config variable this way:
try {
var config = yaml.load(program.config);
} catch (e) {
console.error('unable to load configuration, Error:', e.message);
process.exit(1)
}
Which works.
I now would like to access to the content of the var in project/js/*.js, but I got config is undefined.
Why? Isn't config not supposed to be accessible everywhere?
** EDIT **
My code in *.js:
var fetchMail = function() {
console.log(config); // config undefined
// Other stuff
};
And how I export my code in app.js: export.config = config. And then require it in *.js: var app = require(../app);
I assume you need to change
export.config = config to exports.default = config.
If you are exporting something else than exports.config = config.
In other file you need either
import { config } from ..
or
var config = require(...).config;
You should put var config = null on top of try and you than can access the config variable. Initializing var inside try will create the variable inside that scope. Therefore, you can't be accessing config variable.
Related
I want to launch a js file in a js file with different permission. Just like this:
main.js (which gets started)
config = JSON.parse(require("./config.json")) // <- should be possible
console.log(config.authkey) // <- should be possible
require("./randomJSFile.js").run()
randomJSFile.js (which will be executed by main.js)
exports.run = () => {
let config = JSON.parse(require("./config.json") // <--- this should not be possible, only the main.js file should have access to the config.json file
console.log(config.authkey) // should not be possible
}
Does anyone know how to do something like that?
Based on a snippet from this question here you could possibly override the require function to check for the filename, something like this:
const Module = require('module');
const originalRequire = Module.prototype.require;
Module.prototype.require = function() {
if (!arguments.length || typeof arguments[0] !== 'string') return {};
if (arguments[0].includes('config.json')) return {};
return originalRequire.apply(this, arguments);
};
And then perform this override after you've already required the config in your main file, so you don't accidentally block yourself
I am trying to assign the app object from electron but it returns as undefined. I have tried to debug this but i cant for the love of god find out what is wrong. Here is a snippet of my logic
const ClientBootstrapper = function() {
this.App = null;
this.Init = function() {
const app = require('electron').app;
console.log(app); // undefined???
return // for debug
this.App = app;
});
});
module.exports = new ClientBootstrapper();
Why does this not work and how should i do it?
The reason this failed is because i forgot to switch the start script from using node. Requiring electron in a node results in the path to electron instead.
I have a nodejs package and i have a linkedList code. I want to include my LinkedList code in my NodeJs js folder but I can't do it. What is the my fault ?
I want to use it like this
This is my code in my NodeJs folder.(app.js)
var KullaniciJS=require('KullaniciLibrary.js');
This is my required folder codes.(KullaniciLibrary.js)
function Kullanici(KullaniciAdi)
{
this.KullaniciAdi=KullaniciAdi;
this.Sonraki=null;
}
function KullaniciListe()
{
this.Bas=null;
this.Uzunluk=0;
}
KullaniciListe.prototype.Ekle=function(EklenecekKullaniciAdi)
{
var Bas=this.Bas;
if (!Bas) {
this.Bas = EklenecekKullaniciAdi;
this.Uzunluk++;
return EklenecekKullaniciAdi;
}
while (Bas.Sonraki!==null) {
Bas = Bas.Sonraki;
}
Bas.Sonraki = EklenecekKullaniciAdi;
this.Uzunluk++;
return EklenecekKullaniciAdi;
};
First you have to declare inside of your KullaniciLibrary.js file, what you want to export. you do this by adding following line at the end of the file:
module.exports = YOUREXPORT;
YOUREXPORT will probably just be the methodname (or some object).
After that, you wanna import it like this:
var KullaniciJS = require('./KullaniciLibrary');
Note that you have to prefix the name with ./ and you don't need to define the file-ending.
If you don't prefix the module with ./, node will search for the module in the node_modules folder, instead of the current directory
In nodejs to require a function from another file you have to export then function.
To export the function use:
module.export='your function name';
and to require the function use:
const variable=require(./filename)
for more understanding use this link:
https://nodejs.org/api/modules.html
In MyModule folder, I have this two JS files.
SayHello.js
module.exports.SayHello = function() {
return('Hello !');
}
SayByeBye.js
module.exports.SayByeBye = function() {
return('Bye Bye!');
}
In Node.js, I want to require all files in MyModule folder and call function SayHello & SayByeBye directly something like:
require(./MyModule)
console.log(SayHello());
console.log(SayByeBye());
EDIT:
With answer of #Yanick Rochon,I do this :
> ./app/my-module/index.js
global.SayHello = require('./my-module/SayHello').SayHello;
global.SayByeBye = require('./my-module/SayByeBye').SayByeBye;
> ./app/my-module/say-hello.js
module.exports.SayHello = function() {
return('Hello !');
};
> ./app/my-module/say-byebye.js
module.exports.SayByeBye = function() {
return('Bye Bye !');
};
> ./app/main.js
require('./my-module');
console.log(SayHello());
console.log(SayByeBye());
There's a section about global objects in the node documentation.
However, globals should be used with care. By adding modules to the global space I reduce testability and encapsulation. But in this case, I think using this method is acceptable.
First thing first...
I believe you are mistaking Node.js with PHP or .Net, in the sense that you don't "import" into the current module what is exported in other modules. Not unless you manually do it anyway. For example, when you call
require('./my-module');
(Note that I renamed your MyModule into Node.js naming convention.)
You don't load things into the current context; you just load the script and don't assign it to anything. To access what my-module exposes, you need to assign it, or use it directly. For example :
require('./my-module').someFunction();
or
var myModule = require('./my-module');
myModule.someFunction();
Modules are not namespaces, but JavaScript objects that exposes public properties outside of their own contexts (i.e. using module.exports = ...)
Answer
You have two most popular ways to accomplish this :
Solution 1
Create an index.json file inside your folder where you want to load all of your scripts. The returned JSON object should be all the modules to load automatically :
> ./app/index.json
[
"say-hello.js",
"say-goodbye.js"
]
You should also consider having all your files API compatible :
> ./app/say-hello.js
module.exports = function sayHello() {
return 'Hello !';
};
> ./app/say-goodbye.js
module.exports.sayGoodbye = function () {
return 'Goodbye !';
};
Then load and execute everything like this :
var path = require('path');
var basePath = './app/';
var files = require(basePath);
var mods = files.forEach(function (loaded, file) {
var mod = require(path.join(basePath, file));
// mod is a function with a name, so use it!
if (mod instanceof Function) {
loaded[mod.name] = mod;
} else {
Object.keys(mod).forEach(function (property) {
loaded[property] = mod.property;
});
}
}, {});
mods.sayHello();
mods.sayGoodbye();
Solution 2
Read all .js files inside your folder and import them. I highly recommend you use glob for this.
var glob = require("glob")
var path = require('path');
var basePath = './app/';
var mods = glob.sync(path.join(basePath, '*.js')).reduce(function (loaded, file) {
var mod = require(file);
// mod is a function with a name, so use it!
if (mod instanceof Function) {
loaded[mod.name] = mod;
} else {
Object.keys(mod).forEach(function (property) {
loaded[property] = mod.property;
});
}
return loaded;
}, {});
mods.sayHello();
mods.sayGoodbye();
Note on the difference between module.exports and exports
Typically module.exports === exports, but it is recommended to use module.exports for the following reason
exports = function Foo() { } // will not do anything
module.exports = function Foo() { } // but this will do what you expect
// however these two lines produce the same result
exports.foo = 'Bar';
module.exports.foo = 'Bar';
For this reason, module.exports is recommended in all cases.
It's not perfect, but something like this should help you accomplish this:
var fs = require('fs');
var path = require('path');
var files = fs.readdirSync(__dirname);
var ownFilename = __filename.substr(__filename.lastIndexOf(path.delimiter) + 1);
var modules = {};
for (var i = 0; i < files.length; i++) {
var filename = files[i];
if (filename.substr(-3) === '.js' && filename !== ownFilename) {
modules[filename.slice(0, -3)] = require('./' + filename);
}
}
console.log(modules.SayByeBye());
console.log(modules.SayHello());
I have multiple nightwatch tests with setup and teardown in every single test. I am trying to unify it into globalModule.js in before after(path set in globals_path in nightwatch.json).
//globalModule.js
before:function(test, callback){
// do something with test object
}
//sampletest.js
before: function(test){
..
},
'testing':function(test){
....
}
My problem is test context is not available in globalsModule.js. How do i get it there? Can someone let me know?
Test contex not available now. As said beatfactor, it will available soon.
While it not available try use local before first file, but it hack.
Also you can export all your file into one object and export it into nightwatch, but then you can use local before just in time.
For example:
var tests = {};
var befores = [];
var fs =require('fs');
var requireDir = require('require-dir');
var dirs = fs.readdirSync('build');
//if you have dirs that should exclude
var usefull = dirs.filter(function(item){
return !(item=='data')
});
usefull.forEach(function(item){
var dirObj = requireDir('../build/' + item);
for(key in dirObj){
if(dirObj.hasOwnProperty(key))
for(testMethod in dirObj[key])
if(dirObj[key].hasOwnProperty(testMethod))
if(testMethod == 'before')
befores.push(dirObj[key][testMethod]);
else
tests[testMethod] = dirObj[key][testMethod];
}
});
tests.before = function(browser){
//some global before actions here
//...
befores.forEach(function(item){
item.call(tests,browser);
});
};
module.exports = tests;
For more information https://github.com/beatfactor/nightwatch/issues/388