Ok, so in my previous post, I introduced Node to newcomers. And I am in now way condescending towards people new to Node. But, wait…Chris, you are always condescending!? Not quite true, but in this case I am definitely not, as I am myself a n00b in the area.
The goal with my blogging about node is to share the stuff I learn along the way, in a way that I think make sense to a C# dev like myself. It might not be the correct node lingo, and I might be wrong in some cases, but I just call it as I see it…
This time around, it is time to have a look at modules in node, and how we load them.
In .NET, as in many other languages, we group our code together physically in some form of unit. In the .NET case, is is grouped together in assemblies. In node, as we are generally not compiling our code into dll:s, it is a bit different.
But before I go any further, I want to touch on one thing. One thing that had me going back and changin the last sentence in the previous paragraph from “we are no” to “we are generally not”. Nodule modules come in 2 forms. There is the simple kind of module that I will be talking about, that is just a grouping of JavaScript, and then there are the native modules that are written in C++ and compiled and stuff, and then loaded into node using JavaScript. But as I said, I will be covering the simpler, more common one.
Modules also loaded in 3 different ways, as far as I can see at least. First off the bat are node’s built in modules, or “core” modules, such as “http”. They come with the installation of node. Next you have modules that are installer globally on the server. And finally you have the local modules that are only available to your application.
And if we focus on the local modules to begin with, they come in 2 forms. The one I will cover a bit more in depth later in this post, are our own simple little modules, which are more a matter of loading in external JavaScript files. And then there are the pre-built ones you get off the web. They differ a bit in the way that they are loaded, but generally, they are pretty similar.
Ok, I think that covers the diferent types of modules…
In the previous post, I created a very simple http server that said “hello world”. It started out with just alerting the information to the console, but was quickly transformed into an http server by “requiring” the core module called “http”.
So to move it into C# terms, modules are a lot like assemblies, and using require() is like adding a reference and putting in a using statement in your code…
Loading up core modules is apparently easy. We have already seen that. Just figure out the module you need, and then require() it using its name. But how about we write some modules on our own…
Writing modules is really easy. All there is to it, is to create a new .js file, and add some code to it. There are two things to note though. Modules create their own context, and thus will not put code in the global namespace. It is all kept inside the module, which brings me to the next thing to note. Nothing that you add into the js file will be available outside the module unless you explicitly expose it.
Exposing something from a modules is just a matter of adding it to the implicitly available object called “exports”. The exports object is the object that is returned when invoking require().
A very simple module, exposing a single method called hello, would look something like this
exports.hello = function() { console.log('Hello from module!'); };
Adding that line of code into a JavaScript file named “module.js” results in a brand new module. And no, you do not need to name it “module.js” to make it a module…
Next up is to create an application that uses the module. In my case, I add another JavaScript file called “server.js” and add the following.
console.log('Loading modules\r\n');
console.log('Requiring module.js module - require(\'./module.js\')');
var mymodule = require('./module.js');
mymodule.hello();
And running the application results in this
As you might have noticed, when invoking require() method, I prefix the module filename with “./”. Any string sent to require() starting with “./” or “../” indicates that you are loading a local module file.
So using that simple idea of eposing things through the exports object, and adding a simple require() call makes it really easy to split the application in to several files. And of course, you can split them in to subfolders as well, which is something I think you should. Just treat any module id that startw with “./” as starting from the root of the application, and any starting with “../” as starting a level up.
So adding a folder called “mymodule” and then placing a new JavaScript module in it named “mymodule.js” would require a syntax like this
var mymodule = require('./mymodule/mymodule.js');
But if you start breaking your up your applications into smaller modules, and splitting them into separate folders, then it might be good to know that if you name the module file “index.js”, you don’t need to include the filename…just like with old HTML sites where the IIS would default to index.htm.
Having an “index.js” file in a sub folder called “myindexmodule” would therefore require the following code to get it loaded
var myindexmodule = require('./myindexmodule');
Ok, so that is pretty easy to get your head around. The next thing is not much harder, but still another feature that is good to grok (get a hang of, understand etc…). It is that you can add something called a package.json file. This file contains information about the module in the specific directory. Information like what file is the “entrypoint” for it, what version it is etc. You can put loads of things into the package.json.
To show this off, I create a new sub directory called “mypackagemodule”. Inside it, I add a “mypackagemodule.js” module file (exposing the same old hello() method as previous examples). Next I add another text-file in there, naming it “package.json”. Inside the json-file, I add the following
{
"name": "modulepackagemodule",
"description": "A sample module that is loaded using a package.json file instead of being named index.js",
"version": "0.0.1",
"main": "mypackagemodule.js"
}
As you can see, I am giving my module a name, a description, a version and a “main” property pointing towards the JavaScript containing the module “entrypoint”.
You can add a LOT more stuff in there, and you can find exactly what here. But the important thing to include is name and version. This file is then used by the require() method when loading the module. It is also used by the npm registry, which is something I will get back to in a little while.
From a C# point of view, the package.json is a lot like the manifest we get for assemblies…just a bit more flexible, or less strict depending on how you see it…
Ok, so having added my module implementation and my package file in the directory, I can then load the module in the same way as I did with the index.js file, without the filename…
var mypackagemodule = require('./mypackagemodule');
But what about the last set of modules. The ones you get off the web? Well, they are really easy to get hold of using a tool called npm, which is included in node when you install it.
npm stands for Node Package Manager, which makes it clear that it is in fact a package manager… But to most Windows users, like myself, that doesn’t say a whole lot. But to people using other OS:es, package managers have been around for ages.
A quick intro to package managers… They are basically small tools made for installing stuff on your machine. They run off to some form of registry to find the required “package” and the installs it on your machine for you. For Windows, there is one called Chocolatey which is quite awesome. I suggest having a quick look at it as it enables you to get a lot of your essential dev software onto your machine quickly, or even using a script.
For node, npm will download node modules for you from the npm registry located at http://npmjs.org/, which also has a great little page for you to search and find the modules you need.
People building node modules can upload their packages and make them available to other devs to install using npm. However, they need to find a unique name, as all modules are installed based on name. So you will find some really cool and creative module names up there…
Ok, so how do you go about using npm? Well…it is really complicated. You open up the command prompt and point it at your applications directory, and then write
that command will make npm run off to the npm registry, locate the module you have chosen, and then download it into a “node_modules” directory, which require() will use to locate modules without a “./” or “../” prefix.
If you want to install a module globally, and make it available to the entire machine, just add “-g” to your command
node install modulename -g
And yes, there is a lot more you can do with npm. Just use the helo command to find out more…
Ok, so now that we know how to use npm, let’s try it out. First, I run the following command in my application directory
which will install the “colors” module.
The colors module offers the ability to change the color of the console out put, which seemed like a useful thing…
Next I require the module using the module name
var colors = require('colors');
And then I can make my console output beautiful by adding “.rainbow” to my string
console.log('Hello world! OMG Rainbows!'.rainbow);
which outputs something like this
I think that covers a lot of the basics when it comes to creating and loading modules…
There is obviously code available for this as well.
Get it from here: hello-moduleloading.zip (10.98 kb)
Any questions? Use the comments field…
Cheers!