node.js and browser code reuse: importing constants into modules - javascript

I have some constants in JavaScript that I'd like to reuse in several files while saving typing, reducing bugs from mistyping, keeping runtime performance high, and being useful on either the node.js server scripts or on the client web browser scripts.
example:
const cAPPLE = 17;
const cPEAR = 23;
const cGRAPE = 38;
...(some later js file)...
for...if (deliciousness[i][cAPPLE] > 45) ...
Here are some things I could do:
copy/paste const list to top of each file where used. Oh, Yuck. I'd rather not. This is compatible with keeping the constant names short and simple. It violates DRY and invites all sorts of awful bugs if anything in the list changes.
constant list ---> const.js
on browser, this is FINE ... script gets fed in by the html file and works fine.
but on node.js, the require mechanism changes the constant names, interfering with code reuse and requiring more typing, because of how require works....
AFAIK This doesn't work, by design, in node.js, for any const.js without using globals:
require('./const.js');
for...if...deliciousness[i][cAPPLE] > 45 ...;
This is the node.js way:
(... const.js ....)
exports.APPLE = 17;
(... dependency.js ... )
var C = require('./const.js');
for...if...deliciousness[i][C.APPLE] > 45.....
so I would either have to have two files of constants, one for the node.js requires and one for the browser, or I have to go with something further down the list...
3 make the constants properties of an object to be imported ... still needs two files... since the node.js way of importing doesn't match the browser. Also makes the names longer and probably takes a little more time to do the lookups which as I've hinted may occur in loops.
4 External constant list, internal adapter.... read the external constants, however stored, into internal structure in each file instead of trying to use the external list directly
const.js
exports.cAPPLE = 17
browser.js
const cAPPLE = exports.cAPPLE;
...code requiring cAPPLE...
node.js
CONST = require(./const.js)
const cAPPLE = CONST.cAPPLE;
...code requiring cAPPLE...
This requires a one-time-hit per file to write the code to extract the constants back out, and so would duplicate a bunch of code over and over in a slightly more evolved cut and paste.
It does allows the code requiring cAPPLE to continue to work based on use of short named constants
Are there any other solutions, perhaps a more experienced JavaScripter might know, that I might be overlooking?

module.exports = Object.create({},{
"foo": { value:"bar", writable:false, enumerable:true }
});
Properties are not writable. Works in strict mode unlike "const".

I would just make them global keys:
...(module consts.js)...
global.APPLE = 17;
global.PEAR = 23;
global.GRAPE = 38;
...(some later js file)...
var C = require('./const.js');
for (var i = 0; i < something.length; i++) {
if (deliciousness[i][global.APPLE] > 45) { blah(); }
}
They wouldn't be enforced constants, but if you stick to the ALL_CAPS naming convention for constants it should be apparent that they shouldn't be altered. And you should be able to reuse the same file for the browser if you include it and use it like so:
var global = {};
<script src="const.js"></script>
<script>
if (someVar > global.GRAPE) { doStuff(); }
</script>

You can make an object unwritable using Object.freeze .
var configs={
ENVIRONMENT:"development",
BUILDPATH:"./buildFiles/",
}
Object.freeze(configs);
module.exports=configs;
Than you can use it as constant
var config=require('config');
// config.BUILDPATH will act as constant and will be not writable.

Related

NodeJS: Single object with all requires, or "standard" paths in code?

So, I'm a big fan of creating global namespaces in javascript. For example, if my app is named Xyz I normally have an object XYZ which I fill with properties and nested objects, for an example:
XYZ.Resources.ErrorMessage // = "An error while making request, please try again"
XYZ.DAL.City // = { getAll: function() { ... }, getById: function(id) { .. } }
XYZ.ViewModels.City // = { .... }
XYZ.Models.City // = { .... }
I sort of picked this up while working on a project with Knockout, and I really like it because there are no wild references to some objects declare in god-knows-where. Everything is in one place.
Now. This is ok for front-end, however, I'm currently developing a basic skeleton for a project which will start in a month, and it uses Node.
What I wanted was, instead of all the requires in .js files, I'd have a single object ('XYZ') which would hold all requires in one place. For example:
Instead of:
// route.js file
var cityModel = require('./models/city');
var cityService = require('./services/city');
app.get('/city', function() { ...........});
I would make an object:
XYZ.Models.City = require('./models/city');
XYZ.DAL.City = require('./services/city');
And use it like:
// route.js file
var cityModel = XYZ.Models.City;
var cityService = XYZ.DAL.City;
app.get('/city', function() { ...........});
I don't really have in-depth knowledge but all of the requires get cached and are served, if cached, from memory so re-requiring in multiple files isn't a problem.
Is this an ok workflow, or should I just stick to the standard procedure of referencing dependencies?
edit: I forgot to say, would this sort-of-factory pattern block the main thread, or delay the starting of the server? I just need to know what are the downsides... I don't mind the requires in code, but I just renamed a single folder and had to go through five files to change the paths... Which is really inconvenient.
I think that's a bad idea, because you are going to serve a ton of modules every single time, and you may not need them always. Your namespaced object will get quite monstrous. require will check the module cache first, so I'd use standard requires for each request / script that you need on the server.

Alternatives to eval

My program processes many different types of documents to extract information from them.
It has a very generic structure to fit the hundreds of different types/formats of docs we use.
Processor Code :
Processor.prototype.process = function(){
var self = this;
var fields = self.processor_config;
var p = {};
for(key in fields){
if(fields.hasOwnProperty(key)){
p[key]=self._processKey(fields[key]);
if(typeof(p[key])=='undefined' || p[key]===''){
self.emit('warning', {
type: 'Problem parsing Key',
msg: 'Key : '+key,
doc: self.docName
});
}
}
}
self.emit('extracted',p);
};
The processKey() function then sorts out what to do based on the "type" field :
Productor.prototype._processKey = function(cnf) {
var self = this;
var value;
if(cnf.type=="css"){
value = self._processCSSKey(cnf);
}else if(cnf.type=="regexp"){
value = self._processRegexpKey(cnf);
}else if(cnf.type=="custom"){
value = self._processCustomKey(cnf);
}
return value;
};
Information on what to extract from each type of document comes from a mongodb collection :
Fictional config with 2 types of fields :
doc_name: "FormK7",
processor_config: {
company:{
type:"css"
selector:"p",
ord:3,
attr:{type:"text",parser:""}
},
litigation:{
type:"custom"
func:"(function(){var a =['123'];return a})()"
},
}
The example above is pretty useless, but the real thing has more complicated functions (not much though).
My custom processor looks like :
Productor.prototype._processCustomKey = function(cnf) {
var value = eval(cnf.func);
return value;
};
My problem is that I haven't found a way to process custom keys without using eval. And yet the simple mention of 'eval' brings to my mind pictures of an angry Douglas Crockford banishing me to a dark oblivion for all eternity...
Additional info :
In real life, the function stored in mongo is minified.
The generic processor is needed as having one processor per document type would be extremely wasteful (formats change all the time, there's hundreds of them and some are used once only...). So these functions need to be recorded in some way. And they are too different to be hardcoded...
There is no user input and the app is not accessible from the web. A malicious user would have access to the server before being able to inject code in mongo, so the security concern is extremely low.
So the question is the following :
Is eval really evil in this case, or is it a valid use case? Is there a better way/best practice to handle this?
You could create a module that exports from mongo to a temporal file and then use require to import that file. That way you wont be evaling and, like Bergi mentioned, it would prevent the scope problems that eval has.
Also, once you export it, and before requiring it, you could use something like Esprima to create an AST of the code and analyse it to see if it complies with some criteria you may have. (Like, perhaps, you could forbid the use of this in the code imported as a safety measure - thats part of the rules ADSafe has)

NodeJS - How to reference function in one require() file from another require() file?

This is my second weekend playing with Node, so this is a bit newbie.
I have a js file full of common utilities that provide stuff that JavaScript doesn't. Severely clipped, it looks like this:
module.exports = {
Round: function(num, dec) {
return Math.round(num * Math.pow(10,dec)) / Math.pow(10,dec);
}
};
Many other custom code modules - also included via require() statements - need to call the utility functions. They make calls like this:
module.exports = {
Init: function(pie) {
// does lots of other stuff, but now needs to round a number
// using the custom rounding fn provided in the common util code
console.log(util.Round(pie, 2)); // ReferenceError: util is not defined
}
};
The node.js file that is actually run is very simple (well, for this example). It just require()'s in the code and kicks off the custom code's Init() fn, like this:
var util = require("./utilities.js");
var customCode = require("./programCode.js");
customCode.Init(Math.PI);
Well, this doesn't work, I get a "ReferenceError: util is not defined" coming from the customCode. I know everything in each required file is "private" and this is why the error is occuring, but I also know that the variable holding the utility code object has GOT to be stored somewhere, perhaps hanging off of global?
I searched through global but didn't see any reference to utils in there. I was thinking of using something like global.utils.Round in the custom code.
So the question is, given that the utility code could be referred to as anything really (var u, util, or utility), how in heck can I organize this so that other code modules can see these utilities?
There are at least two ways to solve this:
If you need something from another module in a file, just require it. That's the easy one.
Provide something which actually builds the module for you. I will explain this in a second.
However, your current approach won't work as the node.js module system doesn't provide globals as you might expect them from other languages. Except for the things exported with module.exports you get nothing from the required module, and the required module doesn't know anything of the requiree's environment.
Just require it
To avoid the gap mentioned above, you need to require the other module beforehand:
// -- file: ./programCode.js
var util = require(...);
module.exports = {
Init: function(pie) {
console.log(util.Round(pie, 2));
}
};
requires are cached, so don't think too much about performance at this point.
Keep it flexible
In this case you don't directly export the contents of your module. Instead, you provide a constructor that will create the actual content. This enables you to give some additional arguments, for example another version of your utility library:
// -- file: ./programCode.js
module.exports = {
create: function(util){
return {
Init: function(pie) {
console.log(util.Round(pie, 2));
}
}
}
};
// --- other file
var util = require(...);
var myModule = require('./module').create(util);
As you can see this will create a new object when you call create. As such it will consume more memory as the first approach. Thus I recommend you to just require() things.

Are there any dangers associated with using JavaScript namespaces?

Are there any dangers/caveats one should be aware of when creating JavaScript namespaces?
Our project is fairly expansive and we are running a lot of JavaScript files (20+, expecting more). It is impossible to have any code maintainability without using namespaces, so we are implementing them like so:
var namespace1 = {
doSomething: function() {
...
},
doSomethingElse: function() {
...
}
}
And then to create hierarchies, we link them like so:
var globalNamespace = {
functions1: namespace1,
functions2: namespace2,
...
}
This works fine, but it is essentially a "trick" to make JS behave as if it did have namespaces. Although this method gets used a lot, most literature on this seems to focus on how to do it, and not whether there are any possible drawbacks. As we write more JS code, this is quickly becoming an integral part of the way our system works. So it's important that it works seamlessly.
Were there any situations in which this "induced" namespace system caused you errors, or otherwise needed special attention? Can we safely expect identical behaviour across all browsers?
The way you define namespaces in your example it appears to create globals out of each namespace so you end up with
window.namespace1
window.namespace2
window.globalNamespace
window.globalNamespace.namespace1
window.globalNamespace.namespace2
So if you have anything that clobbers window.namespace1 it will also clobber window.globalNamespace.namespace1
edit:
Here's how we got around this problem:
namespacing = {
init: function(namespace) {
var spaces = [];
namespace.split('.').each(function(space) {
var curSpace = window,
i;
spaces.push(space);
for (i = 0; i < spaces.length; i++) {
if (typeof curSpace[spaces[i]] === 'undefined') {
curSpace[spaces[i]] = {};
}
curSpace = curSpace[spaces[i]];
}
});
}
};
Then you use it like this:
namespacing.init('globalNamespace.namespace1');
globalNamespace.namespace1.doSomething = function() { ... };
This way you don't have to introduce new global variables and you can confidently add to an existing namespace without clobbering other objects in it.
Since you are basically adding functions to objects and those objects into other objects, I would expect each browser to handle this the same way.
But if you want modularity, why not use a (relatively) simple framework like require.js? That will allow you and your team to write code in a modular fashion and allows the team to 'import' these modules where needed:
require(["helper/util"], function() {
//This function is called when scripts/helper/util.js is loaded.
});
Require.js will take care of dependencies, and it will also prevent polluting the global namespace.
We use a similar system at work and it does the job just fine. I don't see any drawbacks there could be; it's just objects and properties. For that same reason, cross browser compatibility should be good. You can end up having to write some long names to resolve to a particular function, like Foo.Bar.Test.Namespace2.Function, but even then that can be solved by assigning it to a variable before hand.
This is how I'd recommend doing it, so you stay out of the global scope entirely except for your "base" namespace. We do something similar where I work. Let's say you work for Acme co, and want ACME to be your base namespace.
At the top of every file, you'd include:
if (!window.ACME) { window.ACME = {} }
Then you just go and define whatever you want in terms of that.
ACME.Foo = {
bar: function () { console.log("baz"); }
}
If you want a deeper level of namespace, you just do the same thing for each level.
if (!window.ACME) { window.ACME = {} }
if (!ACME.Foo) { ACME.Foo = {} }
This way each file can be tested independently and they'll set up the namespace infrastructure automatically, but when you compile them together or if you test multiple files simultaneously, they won't keep overwriting things that are already defined.

Haxe for javascript without global namespace pollution?

This question only applies to Haxe version < 2.10
I've known about haxe for a while, but never really played with it until yesterday. Being curious, I decided to port showdown.js, a javascript port of markdown.pl, to haxe. This was pretty straightforward, and the javascript it generates seems to run fine (edit: If you want to see it in action, check it out here).
However, I noticed that the generated code dumps a ton of stuff in the global namespace... and what's worse, it does it by assigning values to undeclared identifiers without using the var keyword, so they're global even if you wrap the whole thing with a closure.
For example...
if(typeof js=='undefined') js = {}
...
Hash = function(p) { if( p === $_ ) return; {
...
EReg = function(r,opt) { if( r === $_ ) return; {
...
I managed to clean most of that up with sed, but I'm also bothered by stuff like this:
{
String.prototype.__class__ = String;
String.__name__ = ["String"];
Array.prototype.__class__ = Array;
Array.__name__ = ["Array"];
Int = { __name__ : ["Int"]}
Dynamic = { __name__ : ["Dynamic"]}
Float = Number;
Float.__name__ = ["Float"];
Bool = { __ename__ : ["Bool"]}
Class = { __name__ : ["Class"]}
Enum = { }
Void = { __ename__ : ["Void"]}
}
{
Math.__name__ = ["Math"];
Math.NaN = Number["NaN"];
Math.NEGATIVE_INFINITY = Number["NEGATIVE_INFINITY"];
Math.POSITIVE_INFINITY = Number["POSITIVE_INFINITY"];
Math.isFinite = function(i) {
return isFinite(i);
}
Math.isNaN = function(i) {
return isNaN(i);
}
}
This is some pretty unsavory javascript.
Questions
Is there a fork or clone of haxe somewhere that doesn't pollute globals? Is it worth it to modify the haxe source to get what I want, or has someone already solved this? Googling hasn't turned up much. I'm open to any suggestions. Meanwhile, I'm dying to see what kind of PHP code this thing's going to produce... :D
Answers?
Here are some of the ideas I've tried:
postprocessing
Here's my humble build script; it does a pretty good job of stripping stuff out, but it doesn't catch everything. I'm hesitant to remove the modifications to the built-in constructor prototypes; I'm sure that would break things. Fixing everything might be a bit of a task, and I don't want to start on it if someone's already done the work...
haxe -cp ~/Projects/wmd-new -main Markdown -js markdown.js
echo "this.Markdown=(function(){ var \$closure, Float;" > markdown.clean.js;
sed "s/^if(typeof js=='undefined') js = {}$/if(typeof js=='undefined') var js = {};/g ;
s/^\([ \x09]*\)\([\$_a-zA-Z0-9]* = \({\|function\)\)/\1var \2/g ;
/^[ \x09]*\(else \)\?null;$/d ;
" markdown.js >> markdown.clean.js
echo "return Markdown}());" >> markdown.clean.js;
java -jar closure/compiler.jar --js markdown.clean.js \
--compilation_level SIMPLE_OPTIMIZATIONS \
> markdown.cc.js
--js-namespace switch saves the day
Thanks to Dean Burge for pointing out the namespace switch. This pretty much solved my problem, with a minor bit of help. Here's my current build script. I think this catches all the global variables...
NS=N\$
haxe -cp ~/Projects/wmd-new -main Markdown --js-namespace $NS -js markdown.js
# export our function and declare some vars
echo "this.markdown=(function(){var \$_,\$Main,\$closure,\$estr,js,"$NS"" > markdown.clean.js;
# strip silly lines containing "null;" or "else null;"
sed "/^[ \x09]*\(else \)\?null;$/d ;" markdown.js >> markdown.clean.js
# finish the closure
echo "return "$NS".Markdown.makeHtml}());" >> markdown.clean.js;
I use the namespace switch on the compiler to clean those global root types up.
Haxe is not meant to be used for writing an isolated reusable component in a javascript web application. This is evidenced by the fact that the compiler emits standard library for every goddamn compilation. Most optimal use of javascript target is to write an application entirely in haxe and call external stuff using untyped blocks hoping it won't break anything. You should treat haxe output like a flash clip, oblivious to the environment it runs in, assumes it is the only thing running.
Or you might try wrapping the code with a with() block.
there's a namespaced (experimental) haxe compiler here http://github.com/webr3/haxe
The JSTM JavaScript generator macro optimizes haxe output in a number of ways:
the javascript output is split into seperate files per type
these files are optimized
a loader script loads the required types asynchronously
only one global variable is used: jstm
only code that is actually required to run your app is downloaded
new types can be loaded at runtime which makes possible highly scalable apps
check out http://code.google.com/p/jstm/ for more info.

Categories