Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
tree: b9084ea739
Fetching contributors…

Octocat-spinner-32-eaf2f5

Cannot retrieve contributors at this time

file 120 lines (73 sloc) 18.861 kb

Introduction

Hi guys. Well it's been a little while since our last session, and I do appologize for such a long hiatus, but I'm back now and I'm looking forward to continuing this series on node development.

This session will be sort of a hodgepodge of different topics that I think will be of good use to anyone who is considering making Node a regular staple of their development tool belt.

We've got a bit of a taste for node after our first two sessions, and now I want to go off on a bit of a tangent and dive into some of the infrastructure that's grown up around node to help make developing in it much easier. Today will be all about learning some of the tools and concepts that will, hopefully, make you much more effective and will also aid you in the completion of this series.

So, considering that it's been such a long break since our last session, and, in the interim, Node has advanced from release 0.4.5 to 0.6.10, I think a good topic to start off with would be the Node Version Manager, or nvm as it's typically referred to. As the name suggests, nvm will allow you to install and switch between several different versions of Node. Coupled with another excellent tool for managing package installations called npm, you can create virtual environments around specific versions of both node and third party libraries making development much easier, especially considering the volatility of the node world.

After exploring these two pieces of software, we'll put them to use by creating our own virtual environment for the development of our blog system. We'll install a couple of third party packages to this environment, one of which will help make our development go a bit faster, and the other will give us the ability to use templates when defining our views. Before finishing this "hands on" portion of our screencast, I'll go over one more very handy tool for development---the debugger---which, though not terribly full-featured and a bit clumsy at times, it will, nonetheless, be an absolutely invaluable addition to your development arsenal.

Finally, before we end this session, I've received a few requests to explain how node works, specifically, what makes it different from more traditional thread-based systems. I'm going to run through an explanation that I hope will be both intuitive and enlightening. Node is a great tool, but it's meant for a very specific purpose, and like all things, it has advantages in certain situations and disadvantages in others. It's my hope that, armed with a deeper understanding of what node does that makes it such a great tool in certain circumstances, you'll be better equipped for deciding when to use, as well as, when not to use node for your development.

So, apologies made and summary out of the way, let's get right down to business.

Installation Steps

  1. Install a version manager (n) NOTE: These steps you are starting fresh (i.e., no prior node installed)
    1. git clone https://github.com/visionmedia/n.git
    2. cd into n directory 3a. Make install (default path)
      1. make install (by default will install into /usr/local/bin) 3b. Make install (custom path)
      2. mkdir -p ~/.n/bin
      3. export PREFIX=~/.n
      4. make install
      5. Add the following lines to ~/.*rc file export N_PREFIX=$HOME/.n export PATH=$PATH:$N_PREFIX/bin
      6. source ~/.*rc 3c. By hand
      7. mkdir -p ~/.n/bin
      8. cp bin/n ~/.n/bin
      9. Add the following lines to ~/.*rc file export N_PREFIX=$HOME/.n export PATH=$PATH:$N_PREFIX/bin
      10. source ~/.*rc
  2. Explore n a bit

    1. n - list
    2. n -h - list help
    3. n ls - view available versions
    4. n --latest - output the latest version available
    5. n latest - install latest
  3. Install a version of node

Node.js Screencast -

Node Version Manager (NVM)

  • Installing nodes
  • Viewing which nodes you are using and have installed
  • Aliases (stable, dev, default)

Node Package Manager (NPM)

Installing packages (local vs global)

Supervisor

Swig

Introduction

DRY'ing up the code

Now, the code that we've created so far is not the prettiest, and it certainly is not the DRYist. You can already see a few problems with what we've created so far. First, as we add more routes, the number of functions that we need to create for each begins to grow rapidly and just coming up with unique names to identify each one can become quite a task. Next, the if statement that are creating to figure out which route goes to which function may be alright for a single route or two, but quickly becomes a mess of spaghetti code in no time so we'll need to revamp the way that we do dispatching at some point. Third, the view that we've created is just a simple HTML file. What happens once we need some of the elements in the view to be dynamic? Finally, loading all of our views at the very begining of our app's life seems just plain silly. For one, if we have a view that is rarely seen by the user, then it's just taking up space and making startup take longer for no good reason if the chance of it being seen is very small. Another reason why this could cause problems is what happens if we find a mistake in our view's markup? Right now we'd have to restart our server just to make a small change to the markup and that doesn't sound like a very good idea. So, you see, we've come a long way, but we've still got quite a long journey ahead before I would even consider running this piece of code in production.

So, we've identified some problem areas and we want to do a little refactoring to our code to make it a bit more maintainable. Of the items we just identified the ones that we are going to tackle first are the latter two dealing with the way we load our views. What we really want here is some type of templating system and lucky for us, the Node ecosystem happens to have a few that we can take advantage of. For our app we are going to use a templating system called Jade, but before we can use it, we've got to install it and for that we need to learn a bit about an app called npm.

Introducing npm

Node has a package management system similar to systems for other languages such as CPAN, PyPI, and Gems. This package manager, as I already mentioned, is called npm which, of course, stands for the Node Package Manager. It's dead easy to install and use, so we are going to install it now and use it to install Jade to our system. To Install npm, go to its website and copy the line that begins with curl underneath the "One Line Install" header and paste it into your command line. This will download a simple installation Shell script and run it to install npm. So, let's do that now.

Once you've got npm installed, test it out by running npm -v to print the currently installed version, which as of this screencast is version 1.0.3, so you should see something along those lines appear on the screen.

npm Basics

npm has several useful commands that you can see by simply running npm from the command line without any arguments, like so. You should know that you can get a simple manpage for any of these commands by running npm help command-name or you can also get a short summary of what the command does by calling npm command-name -h. Let's try that out with a couple commands now.

First, we'll take a look at the list command. We can see here that the list command essentially shows us what packages we have installed on our system. Let's try it out now. Hmm, (empty), not very interesting. Let's try to find our Jade package and get it installed then. Let's check out the search command. Just type npm help search, ah, now that sounds more like it. The search command will search the registry of available packages and let us know what all it finds. Let's try that out now and search for Jade. There we go, the fourth result down from the top is the Jade template engine. That's exactly what we're looking for, so let's install that now.

To install Jade, you simply need to run the npm install jade command, but before we do let's talk a bit about the two different types of installs that you can do with npm. When npm made the jump to 1.0, it added a new way to do things. In the past, when you called the install command, the specified package would be installed into a global location available to all of your Node apps. With the 1.0 release however, the default is to install the package locally with the option to specify a -g switch which will turn on global installs. The rule of thumb here is that if the package you want to install is a simple library, you should probably install it locally. Doing so means that you have all of your apps dependencies neatly stored within the app's main directory, so deployment is simply a matter of copying the main directory over to your server. On the other hand, if the package comes with global functionality, such as scripts that you can run to perform actions, such as we'll see in a bit with Jade, then you may want to install it globally so that functionality is available to you at all times. Jade, as we'll see is both, it is a library for us to use in our apps, but also a command line program for turning Jade template files into HTML from the command line. In this special case, it is recommended to install the package both globally and locally and that is what we are going to do now.

Let's start by installing globally by calling npm install jade -g. Now, if we call npm ls we should see the newly installed package in our list. Well, what's this, the command still says (empty). Hmm, well what if we also tack the -g flag onto the end of the list command like so. Ah, now we see that Jade has indeed been installed to our system. Remember that anytime you want to see or do anything globally with npm, you must use the -g flag, otherwise, you'll be doing everything from the current directory. Before we install Jade locally, I want to point out one more thing here. Notice too that npm is also in our list of installed packages. That is because npm can also manage itself as well, so now when new updates of npm are available, rather than going through the installation proces again, you can simply update npm like you would any other package---by calling npm update npm. Nice, huh? Finally, one other little thing I'd like to point out is that the list command is showing us a tree structure rather than a list of installed packages. The reason for this is to show the dependencies that packages have on others. So, while Jade has no dependencies, according to the output of the npm list command, npm itself has four packages that were installed as dependencies for it.

Test Jade out with the jade command line script

Since we've installed Jade globally we will have access to a script that comes with Jade that can be used translate our Jade files into HTML. Let's try that out now just to get a taste of what Jade can do. Flip over to the Jade website and copy the sample Jade file that shows up on the homepage. Then create a new file called test.jade. You can create it anywhere you like since this is only for test purposes. I'm going to create mine in the /tmp folder. Once you've got the file created, you can run the jade script against it by calling jade test.jade from the command line. Hmm, so that seems to have caused some problems though. Let's take a look and see what the issue is. It looks as if a variable within the template called pageTitle is undefined. So, let's take a look at the help for the script and see if there are any options we can use to define the variables. To do that call jade --help, and from the looks of it the very first option, -o will allow us to pass in a JavaScript object as a string to define all of the variables within the file. Let's try that now. From the command line let's call jade test.jade -o "{pageTitle: 'Hello World'}". Well now, that still didn't seem to work. The reason for this is that the options object for Jade has several high-level attributes that can be defined, one of which is the locals attribute which is another object of local variables that can be accessed within the template file. So, if we make our object the locals attribute of the object we're passing into the jade command, it should work. And, it looks like that resolved our issue, but now we see that there's another variable we are missing. From the output of the script and the name of the variable, I'm going to guess that it is a boolean value and set it to true in our options object. This time we see the message "compiled test.html" so we can be assured that we were able to process the Jade file properly. Let's open the file that was created and take a look at the output. It's slightly messy, so let me just clean that up for you. There, that's better. Now if we compare this file to the one on the website we'll see that they are for all intents and purposes identical. This script can be pretty useful in many scenarios. When developing your application, it can be nice to have a script like this to see the actual HTML output. Since the script can be set to watch files for changes and recompile them accordingly it can also be used to create static websites as well. For our project though, we want to use it in our application and so, for that reason, we are also going to install it locally so that we can simply copy our app's directory over to the server for it to work.

Install jade locally (talk about the node-modules directory)

To install locally, make sure that you are in the top level directory of your app---in our case, this is the blog directory---and call the npm install jade command again, though this time without the -g option. Once finished, you should see a new directory called node-modules in the root directory of the app.

the node-modules directory is a convention of Node's. Whenever you call the require function in a node app and pass in a string that does specify a native module of Node's, or a relative path to a module file, Node will begin looking for the module's file. It will do so by starting with the current directory and looking for the file in the node-modules directory within it. If it does not find the file there, it will move up a directory and look within the node-modules directory there. It will continue to do this until it either finds the file or reaches the root of the directory tree.

Now that we've got Jade installed, we can create our actual view. I'm not going to go over the specifics of Jade in this set of screencasts simply because there's not much to it. If you already have experience with HTML, then it'll only take about an hour tops to get well enough acquainted with Jade to be effective. If you have any experience with HAML, you'll find yourself very comfortable using Jade. For our purposes, however, we are going to take what we have already and use another tool to convert that into Jade markup. The name of that tool is html2jade and I'm going to install it globally since it is just a simple command line script and not a library that we need to include with our app. If you plan on using Jade again in the future, it is a good tool to have and very helpful when learning Jade. Nevertheless, If you prefer, you can install your copy locally, you'll just have to remember that the script will not be available globally. Instead, you'll need to give the relative path to the script which will be found in the bin directory of the html2jade directory inside of the local node-modules directory. Let's go ahead and install that now. Now let's run that and pass in the name of our HTML file. That should create a new file for us in the same directory as the HTML file with the name of the original file, but with the .jade extension.

Let's open that up now and just take look real quick. As you can see it's quite a bit less verbose than normal HTML. In addition, where HTML uses opening and closing tags to indicate hierarchy, Jade, like Python, uses whitespace. This give Jade a very clean feel compared to HTML.

Now that we've generated our view in Jade, let's flip back over to the Jade website and see how to use it in our app. If you scroll down the page just a bit, you'll run into a section called Public API. This short section describes how to use the library within your application to render Jade templates. It's very simple, just require the Jade module and call the renderFile method. Flip back over to your app.js file and add a require command to the top of the file to require the Jade module. Then let's skip down to the renderNewPostForm function and replace this code with a call to Jade's renderFile method instead. Then, we can safely remove the call to read the original HTML file. Finally, since we are no longer reading anything from the file system, we can also remove the statement to require the fs module. Go ahead and save that and then jump out of their back to our main application directory. Since we are no longer using the new.html file, we can safely remove it as well now. Now, for the real test, let's run our app again and make sure that we didn't break anything after this last round of changes. And, there we go, looks like we migrated our app over to using the Jade templating language without breaking a single thing. Congratulations!

Wrap Up

Well, that pretty much brings us to the of this episode. We've covered quite a lot of ground today. We started off this screencast with a simple web server that served a single line of text, "Hello World" and we've ended with our first route serving an HTML form derived from a whitespace significant templating library. Along the way, we've learned a bit more about Node and quite a bit about the Node packaging tool npm. We've used npm to install our first third party library and incorporated that library into our application. When you think about it, that's quite a significant amount of work. Add to that the fact that your application is not an add on to a web server, but an entire web server in and of itself and it is truly remarkable that we are still only at about 30 lines of code. Not too bad for a days work.

In our next episode, we'll learn a bit about CommonJS, a project whose goal is to aid in the building of an ecosystem for JavaScript outside of the browser. We'll learn how to create our own modules following the CommonJS spec. And we'll create our very first module to aid us in the development of the remaining routes for our application.

It should be fun, so I hope you'll all join me again for the next episode. See you soon.

Something went wrong with that request. Please try again.