Is there any way to define a variable to be used only in a package, without exporting it to the client or the server? For example,
//In /packages/fooPackage/foo.js
packageScopedValue = 'foo';
//In /packages/fooPackage/package.js
api.export('packageScopedValue', 'package');
//In /packages/fooPackage/other.js
doStuffWith(packageScopedValue);
Without polluting any other scope?
A package-scoped var is any global that you don't export. If I say foo = "RAAARR" (no var) in pack.js and console.log(foo) in pack2.js, you'll see RAAARR appear. That's because meteor essentially concatenates each js file in the order you give it & then wraps it in an IFFE.
Note that load order does matter!!
api.addFiles(['pack.js', 'pack2.js'], 'client'); //works
api.addFiles(['pack2.js', 'pack.js'], 'client'); //undefined
Related
this is my current code
function includeClass(classname, ctx) {
var txt = fs.readFileSync("socket.io/" + classname + ".js");
return txt;
}
//define globals here
var _PLAYERS = {};
var _SPAWNPOINTS = [];
vm.runInThisContext(includeClass("vector"));
vm.runInThisContext(includeClass("class"));
vm.runInThisContext(includeClass("connectionHandler"));
vm.runInThisContext(includeClass("game"));
But that way, class.js file can't access variables from global scope or other files. because now i get errors like, _PLAYERS or require is undefined. I've tried eval() too, but it didn't do anything at all.
How can I run these js scripts in main script so they get interpreted as 1 whole?
https://nodejs.org/api/vm.html#vm_vm_runinthiscontext_code_options:
Running code does not have access to local scope, but does have access to the current global object.
Your _PLAYERS variable is not truly global, it is local to your script. As well as some other variables (like require) which are also in the module scope.
You can try to assign the needed variables to global object, however, I am not well aware what side effects and complications may follow.
I wanted to include some js files without using require because it would link it to a variable, and i have some functions i would like to call directly. how can i do it ? is it bad practice ?
what i want to avoid is this:
let's say i have tool.js as follow:
function foo() {
log.debug("foo");
}
exports.foo = foo;
in app.js
var tool= require('tools.js');
tool.foo();
i would like to be able to call foo without creating a module for it as if it was define in app.js; like so
foo();
You can require a file and use its functions without assigning it to a variable by using the global object.
file1.js
function logger(){
console.log(arguments);
}
global.logger = logger;
file2.js
require('./file1');
logger('ABC');
This approach would get rid of variable scoping and would pollute the global namespace potentially leading to clashes with variable naming.
You need to use global like this,
======= app.js ======
global.foo= require('tools.js'); // declare as global
foo(); // can be called from all files
In browser, diffrent javascript file share one scope:
a.js:
var a=1; //we add "var", so we not intent it be a global var.
b.js:
console.log(a) //a=1, but b.js can also see this var!
In nodejs:
a.js ....
b.js ....
console.log(a)// b.js cannot see the var, declare by "var" keywork
is there any doc say those difference ?
that is correct. All of the files are loaded in the browser combined but in node.js uses modules per file so basically to combine the files from b.js you need to do
var a=require('a.js');
then your variable will be in a.a
for this to work you need to exports.a=1 in a.js
Be sure to keep in your mind that while javascript is the same language, different programming techniques are used in frontend and backend.
nodejs encapsulates scope per file, sort of like ruby. If you want to share variables you should export them:
file1.js:
exports.a = 5;
file2.js:
exports.b = 6;
main.js:
var file1 = require('./file1.js');
var file2 = require('./file2.js');
console.log(file1.a); // 5
console.log(file2.b); // 6
Anything you export in a file by assigning to export.variablename = yourObject; will be accessible when you include the file from elsewhere: var exportedStuff = require('./file.js') would let you access yourObject at exportedStuff.variablename.
The reason for all of this is to force you to be more organized about how you write your code. As opposed to just slapping global variables around everywhere, it forces you to organize your code into modules, and also gives you the ability to emulate private scoping in an easier way than on the web.
In the web when you omit var, and just have varname = 5 then when variable does not already exist, it's the same as saying window.varname. This is NOT the case in nodejs. In Node if you want to use global you must do global.varname = 5
Hello I am new JavaScript unit testing and I'm using Mocha.js and Chai.js
What I want to do is simply figure out how to check the value of a global variable in a seperate js file. Here is my code
Here is the main.js file (code to be tested) Just has the variable I want to test against.
//main.js
var foo = 9;
Here is my test file
var assert = require("assert")
var expect = require('chai').expect
var fs = require("fs")
var vm = require("vm")
function include(path){
var code = fs.readFileSync(path,'utf-8');
vm.runInThisContext(code,path);
}
describe('Global', function(){
include('lib/main.js');
it('Should check if value is matching', function(){
expect(foo).to.equal(9);
});
});
Again, I'm new to unit testing in JavaScript. Any help will be greatly appreciated. The error I get back is foo is not defined which tells me that it can't access the variable, so how can I access it? Thank you in advance for the help.
var foo = 9; does not declare a global variable, it declares a local variable. In Node.js, a local variable declared in the outermost scope of a module will be local to that module.
If you want to test the value of a local variable declared in another file, your best bet is probably to read the contents of that file into a string (using fs.readFileSync, perhaps) and then eval() the string, which should define the variable in the current scope.
That will only work if the local variable is declared in the file's outermost scope. If it's a local variable inside a function, for example, you're out of luck (unless you want to do some gnarly string parsing, which would stretch the bounds of sanity).
Your global object is usually window
a global var foo = "test"; is the same as window.foo = "test"; or window['foo'] = "test";
Window is not defined when mocha is run in node, but this blog post uses "this" combined with a self-invoking function to get the same result.
i have seen this code :
var myNet = require ("net");
and in some function:
function foo (x,y) {
var myNewNet = new myNet();
myNewNet.createServer(x,y);
}
why does the code above create a new object? what is the mechanism stands behind that?
one more question, how do i create a static var in node.js, for example a id number that has to be unique.
i came with this option for static variable:
var id =0;
and put it on the global scope, is it ok?
The require statement basically is like an import; it takes an external library and makes it available in your code.
If you ever look in an external module, you will notice that it's just normal node.js js code. It has EXPORT statements in it. Those statements are what gets made available when you require something. Check out http://howtonode.org/creating-custom-modules
There is a GLOBAL keyword in node.js you can use to make something global
GLOBAL.IP_ADDRESS = "..."
As #Raynos says, it's not usually a good idea to do that, so another options is to export a constant from a module, so you can create a module and do
exports.STATIC_CONSTANT = "";
and then once you import the module you can do
var mod = require('mymodule');
mod.STATIC_CONSTANT;
EDIT, to answer you comment, the line
var myNet = require("net")
causes myNet to be whatever the net module exports. It must be exporting a function, so
var newNet = new myNet()
creates a new instance of the net object. From there
myNewNet.createServer()
is just invoking a method on the object you just created.