How to manage multiple JS files server-side with Node.js - javascript

I'm working on a project with Node.js and the server-side code is becoming large enough that I would like to split it off into multiple files. It appears this has been done client-side for ages, development is done by inserting a script tag for each file and only for distribution is something like "Make" used to put everything together. I realize there's no point in concatting all the server-side code so I'm not asking how to do that. The closest thing I can find to use is require(), however it doesn't behave quite like script does in the browser in that require'd files do not share a common namespace.
Looking at some older Node.js projects, like Shooter, it appears this was once not the case, that or I'm missing something really simple in my code. My require'd files cannot access the global calling namespace at compile time nor run time. Is there any simple way around this or are we forced to make all our require'd JS files completely autonomous from the calling scope?

You do not want a common namespace because globals are evil. In node we define modules
// someThings.js
(function() {
var someThings = ...;
...
module.exports.getSomeThings = function() {
return someThings();
}
}());
// main.js
var things = require("someThings");
...
doSomething(things.getSomeThings());
You define a module and then expose a public API for your module by writing to exports.
The best way to handle this is dependency injection. Your module exposes an init function and you pass an object hash of dependencies into your module.
If you really insist on accessing global scope then you can access that through global. Every file can write and read to the global object. Again you do not want to use globals.

re #Raynos answer, if the module file is next to the file that includes it, it should be
var things = require("./someThings");
If the module is published on, and installed through, npm, or explicitly put into the ./node_modules/ folder, then the
var things = require("someThings");
is correct.

Related

How to use javascript constant in javascript file from another javascript file

I have created one javascript file in which I have declared different string constants.
now in another javascript file I want to use those String constants from already created javascript file.
Is there any way to do this.
Thanks in advance.
If you declare your constants in file1 as global variables:
var someConstant = 42;
Then you can just use that variable in your other JS files. Just make sure file1 is loaded before you try to use them.
However, polluting the global scope like this come with it's risks, as those variables are easily changed.
Multiple ways.
Concatenate
Use a task runner like grunt to define a task that concatenates your files into a single one. This will not only allow convenient definition of constants but also improve performance.
There are other tools to do this, too. See Prepros for windows and codekit for Macs.
Modularize
If you are on client side, use a tool like require.js or browserify to define commonJS / AMD modules and require them as you need.
If you are on server side using node, this works out of the box for commonJS.
Load scripts in correct order, expose them through global objects.
You could load your constant defining script first and do something like this:
var constants = {
MY_CONST: 'Foo'
}
Your main, whi script could access this variable. If you omit the var keyword, the variable becomes globally available. Note however that this should be avoided.
You could even add a property to the global object (window on the client side).
Personally I like to use commonJS modules when working on projects that allow me to do so. Rob Ashton has an opinion on this that I would like to share.
When I can't use those modules in a convenient way, which would be the case when working with (custom) web-components because of their isolated scopes, I like to add a single script which creates
an Object like App. I use this object to expose modules, services & constants which can then be required by any component in a neat way:
App.myService.doSomething()
Create a file which contains all the constants and variables
Constants.js
const EMAIL = "xyz#gmail.com"
const PHONE = "9911223344"
var NAME = "Default name"
Access the Constants.js file in your HTML file
xyz.html
<script src="Constants.js"></script>
Now you can access the Constants in any of file inside a project

Encapsulating requireJS and its modules

I'd like to use something like requireJS to modularise my javascript app, however, there's one particular requirement I'd like to meet that I haven't figured out:
I'm happy enough to have require and define in the global space, however, I don't want modules that I import with require to be accessible globally (i.e. they should be accessible to my app, but not other apps running on the same page).
It seems to me that if I call define('moduleA', function() { ... }); I can then access that module - globally - via the require function. It may not be occupying a variable in the global space itself, or be attached to window, but it still feels bad, because other apps really shouldn't be able to see my internal modules (not to mention potential naming conflicts, etc, can I use contexts to circumvent this?).
This seems to be a step back from just namespacing my modules and including them all inside of one big privatising function at build time.
I could have my own private version of require but my modules (being in different files) wouldn't be able to access define.
Am I missing something or do I just have to live with this? (or alternatively, run an optimizer to bake everything into one file - feels like I could just namespace my modules and not bother with requireJS at all if I do that though).
In your r.js build config add wrap: true and you will no longer pollute the glabal scope with require or define functions.
Edit:
You can also specify a namespace for your require and define with the namespace setting in the r.js build config. You can read more about namespacing in RequireJS's FAQ. From the example.build.js comments:
// Allows namespacing requirejs, require and define calls to a new name.
// This allows stronger assurances of getting a module space that will
// not interfere with others using a define/require AMD-based module
// system. The example below will rename define() calls to foo.define().
// See http://requirejs.org/docs/faq-advanced.html#rename for a more
// complete example.
namespace: 'foo',

Creating a "controller" script for Node.js

I'm creating a program in Node.js. I'm pretty new to programming anything other than small javascript functions for websites so please bear with me if my terminology/ideas are totally wrong.
I originally had the entire program in one giant (~500 line) script file. Several people suggested I split it up into separate classes, where each class only has one 'job' to complete. I like this idea as it has helped me really streamline my code and make it more modular and manageable.
My issue is: How do I access these classes from a central file?
For instance, pretend I have 3 classes, in 3 separate javascript files, all containing 3 functions each. I want to access and pass data to/from all of these from one central "controller" script. What's the best way to do this? Can I just require it into a variable, then access the script's functions like so?
var class1 = require('./class1.js');
class1.function1(); // call the first function contained in class1.js
Is such a thing even possible? Again, totally new to this.
NodeJS supports CommonJS modules. A CommonJS module provides three global variables: module, exports and require.
You can export your API by adding to the exports object and require these files just like other node modules (add ./ to indicate that it is relative to the current file), assign it to a variable and access the values you added to that files exports object:
// first-module.js
exports.hello = 'world';
exports.num = 23;
// main.js
var first = require('./first-module');
console.log(first.hello);
console.log(first.num);
You need to add functions to the exports object in class1.js.
require("./class1") will return this object.

Transitioning code to RequireJS

TL;DR at the bottom of the question, for those who don't want to read all my junk.
My current method of JavaScript modularization is to simply create a global anchor, like "csc" (my company acronym) and then start tacking modules onto that.
So I'll end up with a global structure like:
csc.
Utils
Map
.Geolocation
Storage.
Cookie
DB
And each of these files are stored in a directory structure:
csc.js
csc.Utils.js
csc.Map.js
csc.Storage.js
This eliminates the need to load my entire codebase all the time.
I'm trying to transition toward using RequireJS, but the methodology employed by that library seems to be a bit different.
In order to maintain my namespaced structure, I could define modules around all of my modules, but still tack them into the global "csc" reference. However this seems to go against the core principles of Require.
Without keeping them global, however, I lose my nice namespacing, such as "csc.Map.Geolocation" because I now have a bunch of separate variables, like so:
require(['csc', 'csc.Utils', 'csc.Map'], function (csc, utils, map) {
});
I'll strip my question down to its essence, in case my horrible description above didn't suffice:
Is there a way, perhaps within the module definitions, to combine these three variables back into the structure defined at the top of this question? Or am I going about this all wrong, and should I instead be adhering to the Require way of doing things?
I'd love to follow the Require methodology, but I also love the ability to have all of my modules chainable and namespaced.
Don't be discouraged by the documentation's example path hierarchy, notice that require does not strictly enforce any particular convention. You are free to design and follow your own convention.
Utils, Map, and Storage all become directories. The base actions that they perform should be named module.js in their respective directories, like so:
core.js
Utils/
module.js
Map/
module.js
geolocation.module.js
Storage/
module.js
cookie.module.js
db.module.js
The module.js files include and return their children. Here is an example of Storage/module.js:
require(["Storage/cookie", "Storage/db"], function (cookie, db) {
var Storage = {};
// do whatever you need with Storage
Storage.cookie = cookie
Storage.db = db
return Storage
});
Notice also the core.js file in root. This file would work just the same,
require(["Utils/module", "Storage/module", "Map/module"], function (utils, storage, map) {
var Core = {};
// do whatever you need with Storage
Core.Utils = utils
Core.Storage = storage
Core.Map = map
return Core
});
Now, require core.js wherever you will need access to these modules (every file basically). Yes, this will load all of the involved files all of the time in development, but when you compile your app, all of your variables will be inside the scope of an anonymous function, and not directly accessible via the window object.
Again, tweak this as you see fit, it's your own convention.

Approaches to modular client-side Javascript without namespace pollution

I'm writing client-side code and would like to write multiple, modular JS files that can interact while preventing global namespace pollution.
index.html
<script src="util.js"></script>
<script src="index.js"></script>
util.js
(function() {
var helper() {
// Performs some useful utility operation
}
});
index.js
(function () {
console.log("Loaded index.js script");
helper();
console.log("Done with execution.");
})
This code nicely keeps utility functions in a separate file and does not pollute the global namespace. However, the helper utility function will not be executed because 'helper' exists inside a separate anonymous function namespace.
One alternative approach involves placing all JS code inside one file or using a single variable in the global namespace like so:
var util_ns = {
helper: function() {
// Performs some useful utility operation.
},
etc.
}
Both these approaches have cons in terms of modularity and clean namespacing.
I'm used to working (server-side) in Node.js land where I can 'require' one Javascript file inside another, effectively injecting the util.js bindings into the index.js namespace.
I'd like to do something similar here (but client-side) that would allow code to be written in separate modular files while not creating any variables in the global namespace while allowing access to other modules (i.e. like a utility module).
Is this doable in a simple way (without libraries, etc)?
If not, in the realm of making client-side JS behave more like Node and npm, I'm aware of the existence of requireJS, browserify, AMD, and commonJS standardization attempts. However, I'm not sure of the pros and cons and actual usage of each.
I would strongly recommend you to go ahead with RequireJS.
The modules support approach (without requires/dependencies):
// moduleA.js
var MyApplication = (function(app) {
app.util = app.util || {};
app.util.hypotenuse = function(a, b) {
return Math.sqrt(a * a + b * b);
};
return app;
})(MyApplication || {});
// ----------
// moduleB.js
var MyApplication = (function(app) {
app.util = app.util || {};
app.util.area = function(a, b) {
return a * b / 2;
};
return app;
})(MyApplication || {});
// ----------
// index.js - here you have to include both moduleA and moduleB manually
// or write some loader
var a = 3,
b = 4;
console.log('Hypotenuse: ', MyApplication.util.hypotenuse(a, b));
console.log('Area: ', MyApplication.util.area(a, b));
Here you're creating only one global variable (namespace) MyApplication, all other stuff is "nested" into it.
Fiddle - http://jsfiddle.net/f0t0n/hmbb7/
**One more approach that I used earlier in my projects - https://gist.github.com/4133310
But anyway I threw out all that stuff when started to use RequireJS.*
You should check out browserify, which will process a modular JavaScript project into a single file. You can use require in it as you do in node.
It even gives a bunch of the node.js libs like url, http and crypto.
ADDITION: In my opinion, the pro of browserify is that it is simply to use and requires no own code - you can even use your already written node.js code with it. There's no boilerplate code or code change necessary at all, and it's as CommonJS-compliant as node.js is. It outputs a single .js that allows you to use require in your website code, too.
There are two cons to this, IMHO: First is that two files that were compiled by browserify can override their require functions if they are included in the same website code, so you have to be careful there. Another is of course you have to run browserify every time to make change to the code. And of course, the module system code is always part of your compiled file.
I strongly suggest you try a build tool.
Build tools will allow you to have different files (even in different folders) when developing, and concatenating them at the end for debugging, testing or production. Even better, you won't need to add a library to your project, the build tool resides in different files and are not included in your release version.
I use GruntJS, and basically it works like this. Suppose you have your util.js and index.js (which needs the helper object to be defined), both inside a js directory. You can develop both separately, and then concatenate both to an app.js file in the dist directory that will be loaded by your html. In Grunt you can specify something like:
concat: {
app: {
src: ['js/util.js', 'js/index.js'],
dest: 'dist/app.js'
}
}
Which will automatically create the concatenation of the files. Additionally, you can minify them, lint them, and make any process you want to them too. You can also have them in completely different directories and still end up with one file packaged with your code in the right order. You can even trigger the process every time you save a file to save time.
At the end, from HTML, you would only have to reference one file:
<script src="dist/app.js"></script>
Adding a file that resides in a different directory is very easy:
concat: {
app: {
src: ['js/util.js', 'js/index.js', 'js/helpers/date/whatever.js'],
dest: 'dist/app.js'
}
}
And your html will still only reference one file.
Some other available tools that do the same are Brunch and Yeoman.
-------- EDIT -----------
Require JS (and some alternatives, such as Head JS) is a very popular AMD (Asynchronous Module Definition) which allows to simply specify dependencies. A build tool (e.g., Grunt) on the other hand, allows managing files and adding more functionalities without relying on an external library. On some occasions you can even use both.
I think having the file dependencies / directory issues / build process separated from your code is the way to go. With build tools you have a clear view of your code and a completely separate place where you specify what to do with the files. It also provides a very scalable architecture, because it can work through structure changes or future needs (such as including LESS or CoffeeScript files).
One last point, having a single file in production also means less HTTP overhead. Remember that minimizing the number of calls to the server is important. Having multiple files is very inefficient.
Finally, this is a great article on AMD tools s build tools, worth a read.
So called "global namespace pollution" is greatly over rated as an issue. I don't know about node.js, but in a typical DOM, there are hundreds of global variables by default. Name duplication is rarely an issue where names are chosen judiciously. Adding a few using script will not make the slightest difference. Using a pattern like:
var mySpecialIdentifier = mySpecialIdentifier || {};
means adding a single variable that can be the root of all your code. You can then add modules to your heart's content, e.g.
mySpecialIdentifier.dom = {
/* add dom methods */
}
(function(global, undefined) {
if (!global.mySpecialIdentifier) global.mySpecialIdentifier = {};
/* add methods that require feature testing */
}(this));
And so on.
You can also use an "extend" function that does the testing and adding of base objects so you don't replicate that code and can add methods to base library objects easily from different files. Your library documentation should tell you if you are replicating names or functionality before it becomes an issue (and testing should tell you too).
Your entire library can use a single global variable and can be easily extended or trimmed as you see fit. Finally, you aren't dependent on any third party code to solve a fairly trivial issue.
You can do it like this:
-- main.js --
var my_ns = {};
-- util.js --
my_ns.util = {
map: function () {}
// .. etc
}
-- index.js --
my_ns.index = {
// ..
}
This way you occupy only one variable.
One way of solving this is to have your components talk to each other using a "message bus". A Message (or event) consists of a category and a payload. Components can subscribe to messages of a certain category and can publish messages. This is quite easy to implement, but there are also some out of the box-solutions out there. While this is a neat solution, it also has a great impact on the architecture of your application.
Here is an example implementation: http://pastebin.com/2KE25Par
http://brunch.io/ should be one of the simplest ways if you want to write node-like modular code in your browser without async AMD hell. With it, you’re also able to require() your templates etc, not just JS files.
There are a lot of skeletons (base applications) which you can use with it and it’s quite mature.
Check the example application https://github.com/paulmillr/ostio to see some structure. As you may notice, it’s written in coffeescript, but if you want to write in js, you can — brunch doesn’t care about langs.
I think what you want is https://github.com/component/component.
It's synchronous CommonJS just like Node.js,
it has much less overhead,
and it's written by visionmedia who wrote connect and express.

Categories

Resources