epubjs
Version:
Render ePub documents in the browser, across many devices
439 lines (430 loc) • 43.3 kB
HTML
<html xmlns="http://www.w3.org/1999/xhtml"><head><title>Chapter 1. A Very Brief Introduction to Node.js</title><link rel="stylesheet" href="core.css" type="text/css"/><meta name="generator" content="DocBook XSL Stylesheets V1.74.0"/></head><body><div class="chapter" title="Chapter 1. A Very Brief Introduction to Node.js"><div class="titlepage"><div><div><h1 class="title"><a id="chap1_id35940135"/>Chapter 1. A Very Brief Introduction to Node.js</h1></div></div></div><p><a id="chap1_id35940091"/>Node.js is many <a id="no1.0" class="indexterm"/>things, but mostly it’s a way of running JavaScript outside
the web browser. This book will cover why that’s important and the benefits
that Node.js provides. This introduction attempts to sum up that explanation
in a few paragraphs, rather than a few hundred pages.</p><p><a id="chap1_id35940096"/>Many people use the <a id="ja1.0" class="indexterm"/>JavaScript programming language extensively for programming
the interfaces of websites. Node.js allows this popular programming language
to be applied in many more contexts, in particular on web servers. There are
several notable features about Node.js that make it worthy of
interest.</p><p><a id="chap1_id35940102"/>Node is a wrapper around the high-performance
<a id="I_indexterm1_d1e424" class="indexterm"/>V8 JavaScript runtime from the Google Chrome browser. Node
tunes V8 to work better in contexts other than the browser, mostly by
providing additional APIs that are optimized for specific use cases. For
example, in a server context, manipulation of binary data is often
necessary. This is poorly supported by the JavaScript language and, as a
result, V8. Node’s <code class="literal">Buffer</code> class
<a id="I_indexterm1_d1e433" class="indexterm"/>provides easy manipulation of binary data. Thus, Node doesn’t
just provide direct access to the V8 JavaScript runtime. It also makes
JavaScript more useful for the contexts in which people use Node.</p><p><a id="chap1_id35940114"/>V8 itself uses some of the newest techniques in
compiler technology. This often allows code written in a high-level language
such as JavaScript to perform similarly to code written in a lower-level
language, such as C, with a fraction of the development cost. This focus on
performance is a key aspect of Node.</p><p><a id="chap1_id35940120"/>JavaScript is an event-driven language, and Node
uses this to its advantage to produce highly scalable servers. Using an
architecture called an <span class="emphasis"><em>event loop</em></span>, Node makes
programming highly scalable servers both easy and safe. There are various
strategies that are used to make servers performant. Node has chosen an
architecture that performs very well but also reduces the complexity for the
application developer. This is an extremely important feature. Programming
concurrency is hard and fraught with danger. Node sidesteps this challenge
while still offering impressive performance. As always, any approach still
has trade-offs, and these are discussed in detail later in the book.</p><p><a id="chap1_id35940123"/>To support the event-loop approach, Node
supplies a set of “nonblocking” libraries. In essence, these are interfaces
to things such as the filesystem or databases, which operate in an
event-driven way. When you make a request to the filesystem, rather than
requiring Node to wait for the hard drive to spin up and retrieve the file,
the nonblocking interface simply notifies Node when it has access, in the
same way that web browsers notify your code about <a id="I_indexterm1_d1e448" class="indexterm"/>an <code class="literal">onclick</code> event. This
model simplifies access to slow resources in a scalable way that is
intuitive to JavaScript programmers and easy to learn for everyone
else.</p><p><a id="chap1_id35940193"/>Although not unique to Node, supporting
JavaScript on the server is also a powerful feature. Whether we like it or
not, the browser environment gives us little choice of programming
languages. Certainly, JavaScript is the only choice if we would like our
code to work in any reasonable percentage of browsers. To achieve any
aspirations of sharing code between the server and the browser, we must use
JavaScript. Due to the increasing complexity of client applications that we
are building in the browser using JavaScript (such as Gmail), the more code
we can share between the browser and the server, the more we can reduce the
cost of creating rich web applications. Because we must rely on JavaScript
in the browser, having a server-side environment that uses JavaScript opens
the door to code sharing in a way that is not possible with other
server-side languages, such as PHP, Java, Ruby, or Python. Although there
are other platforms that support programming web servers with JavaScript,
Node is quickly becoming the dominant platform in the space.</p><p><a id="chap1_id35940197"/>Aside from what you can build
<span class="emphasis"><em>with</em></span> Node, one extremely pleasing aspect is how much
you can build <span class="emphasis"><em>for</em></span> Node. Node is extremely extensible,
with a large volume of community modules that have been built in the
relatively short time since the project’s release. Many of these are drivers
to connect with databases or other software, but many are also useful
software applications in their own right.</p><p><a id="chap1_id35940204"/>The last reason to celebrate Node, but certainly
not the least important, is its community. The Node project is still very
young, and yet rarely have we seen such fervor around a project. Both
novices and experts have coalesced around the project to use and contribute
to Node, making it both a pleasure to explore and a supportive place to
share and get <a id="I_indexterm1_d1e467" class="indexterm"/><a id="I_indexterm1_d1e469" class="indexterm"/>advice.</p><div class="sect1" title="Installing Node.js"><div class="titlepage"><div><div><h1 class="title"><a id="chap5_id35941617"/>Installing Node.js</h1></div></div></div><p><a id="chap5_id35940174"/>Installing <a id="no1.1" class="indexterm"/><a id="in1.1" class="indexterm"/>Node.js is extremely simple. Node runs on Windows, Linux,
Mac, and other POSIX OSes (such as Solaris and BSD). Node.js is available
from two primary locations: the <a class="ulink" href="http://nodejs.org">project’s
website</a> or the <a class="ulink" href="http://github.com/joyent/node">GitHub
repository</a>. You’re probably better off with the Node website
because it contains the stable releases. The latest cutting-edge features
are hosted on GitHub for the core development team and anyone else who
wants a copy. Although these features are new and often intriguing, they
are also less reliable than those in a stable release.</p><p><a id="chap5_id35940190"/>Let’s get started by installing Node.js. The
first thing to do is download Node.js from the website, so let’s go there
and find the latest release. From the Node home page, find the download
link. The current release at the time of print is 0.6.13, which is a
stable release. The Node website provides installers for Windows and Mac
as well as the stable source code. If you are on Linux, you can either do
a source install or use your usual package <a id="I_indexterm1_d1e496" class="indexterm"/><a id="I_indexterm1_d1e499" class="indexterm"/>manager (<code class="literal">apt-get</code>,
<code class="literal">yum</code>, etc.).</p><div class="note" title="Note"><h3 class="title">Note</h3><p><a id="chap5_id35940238"/>Node.js version
numbers follow the C convention of
<em class="replaceable"><code>major.minor</code></em><em class="replaceable"><code>.patch</code></em>. Stable versions of Node.js
have an even minor version number, and development versions have an odd
minor version number. It’s unclear when Node will become version 1, but
it’s a fair assumption that it will only be when the Windows and Unix
combined release is considered mature.</p></div><p><a id="chap5_id35940247"/>If you used an installer, you can skip to
<a class="xref" href="ch01.html#chap5_id35941671" title="First Steps in Code">First Steps in Code</a>. Otherwise (i.e., if you are doing a
source install), once you have the code, you’ll need to unpack it. The
<code class="literal">tar</code> command <a id="I_indexterm1_d1e527" class="indexterm"/><a id="I_indexterm1_d1e532" class="indexterm"/><a id="I_indexterm1_d1e537" class="indexterm"/>does this using the flags <code class="literal">xzf</code>. The <code class="literal">x</code>
stands for extract (rather than compress), <code class="literal">z</code> tells <code class="literal">tar</code> to also
decompress using the <a id="I_indexterm1_d1e556" class="indexterm"/>GZIP algorithm, and <code class="literal">f</code>
indicates we are unpacking the filename given as the final argument (see
<a class="xref" href="ch01.html#chap5_id35940266" title="Example 1-1. Unpacking the code">Example 1-1</a>).</p><div class="example"><a id="chap5_id35940266"/><p class="title">Example 1-1. Unpacking the code</p><div class="example-contents"><a id="chap5_id35940271"/><pre class="programlisting">enki:Downloads $ <strong class="userinput"><code>tar xzf node-v0.6.6.tar.gz</code></strong>
enki:Downloads $ <strong class="userinput"><code>cd node-v0.6.6</code></strong>
enki:node-v0.6.6 $ <strong class="userinput"><code>ls</code></strong>
AUTHORS Makefile common.gypi doc test
BSDmakefile Makefile-gyp configure lib tools
ChangeLog README.md configure-gyp node.gyp vcbuild.bat
LICENSE benchmark deps src wscript
enki:node-v0.6.6 $</pre></div></div><p><a id="chap5_id35940282"/>The next step is to configure the code for
your system. Node.js uses the configure/make system for its installation.
<a id="I_indexterm1_d1e581" class="indexterm"/>The <code class="literal">configure</code> script
looks at your system and finds the paths Node needs to use for the
dependencies it needs. Node generally has very few dependencies. The
installer requires Python 2.4 or greater, and if you wish to use TLS or
cryptology (such as SHA1), Node needs the OpenSSL development
libraries<a id="I_indexterm1_d1e590" class="indexterm"/><a id="I_indexterm1_d1e595" class="indexterm"/>. Running <code class="literal">configure</code> will let you know
whether any of these dependencies are missing (see <a class="xref" href="ch01.html#chap5_id35940299" title="Example 1-2. Configuring the Node install">Example 1-2</a>).</p><div class="example"><a id="chap5_id35940299"/><p class="title">Example 1-2. Configuring the Node install</p><div class="example-contents"><a id="chap5_id35940304"/><pre class="programlisting">enki:node-v0.6.6 $ <strong class="userinput"><code>./configure</code></strong>
Checking for program g++ or c++ : /usr/bin/g++
Checking for program cpp : /usr/bin/cpp
Checking for program ar : /usr/bin/ar
Checking for program ranlib : /usr/bin/ranlib
Checking for g++ : ok
Checking for program gcc or cc : /usr/bin/gcc
Checking for gcc : ok
Checking for library dl : yes
Checking for openssl : not found
Checking for function SSL_library_init : yes
Checking for header openssl/crypto.h : yes
Checking for library util : yes
Checking for library rt : not found
Checking for fdatasync(2) with c++ : no
'configure' finished successfully (0.991s)
enki:node-v0.6.6 $</pre></div></div><p><a id="chap5_id35940315"/>The next installation step is to<a id="I_indexterm1_d1e616" class="indexterm"/> <code class="literal">make</code> the project (<a class="xref" href="ch01.html#chap5_id35940324" title="Example 1-3. Compiling Node with the make command">Example 1-3</a>). This compiles Node and builds the binary
version that you will use into a build subdirectory of the source
directory we’ve been using. Node numbers each of the build steps it needs
to complete so you can follow the progress it makes during the
compile.</p><div class="example"><a id="chap5_id35940324"/><p class="title">Example 1-3. Compiling Node with the make command</p><div class="example-contents"><a id="chap5_id35940330"/><pre class="programlisting">enki:node-v0.6.6 $ <strong class="userinput"><code>make</code></strong>
Waf: Entering directory `/Users/sh1mmer/Downloads/node-v0.6.6/out'
DEST_OS: darwin
DEST_CPU: x64
Parallel Jobs: 1
Product type: program
[ 1/35] copy: src/node_config.h.in -> out/Release/src/node_config.h
[ 2/35] cc: deps/http_parser/http_parser.c -> out/Release/deps/http_parser/http_parser_3.o
/usr/bin/gcc -rdynamic -pthread -arch x86_64 -g -O3 -DHAVE_OPENSSL=1 -D_LARGEFILE_SOURCE ...
[ 3/35] src/node_natives.h: src/node.js lib/dgram.js lib/console.js lib/buffer.js ...
[ 4/35] uv: deps/uv/include/uv.h -> out/Release/deps/uv/uv.a
...
f: Leaving directory `/Users/sh1mmer/Downloads/node-v0.6.6/out'
'build' finished successfully (2m53.573s)
-rwxr-xr-x 1 sh1mmer staff 6.8M Jan 3 21:56 out/Release/node
enki:node-v0.6.6 $</pre></div></div><p><a id="chap5_id35940340"/>The final step is to use <code class="literal">make</code> to install Node. First, <a class="xref" href="ch01.html#chap5_id35941575" title="Example 1-4. Installing Node for the whole system">Example 1-4</a> shows how to install Node globally for the
whole system. This requires you to have either access to <a id="I_indexterm1_d1e640" class="indexterm"/>the <code class="literal">root</code> user or <code class="literal">sudo</code> privileges <a id="I_indexterm1_d1e651" class="indexterm"/>that let you act as <code class="literal">root</code>.</p><div class="example"><a id="chap5_id35941575"/><p class="title">Example 1-4. Installing Node for the whole system</p><div class="example-contents"><a id="chap5_id35941581"/><pre class="programlisting">enki:node-v0.6.6 $ <strong class="userinput"><code>sudo make install</code></strong>
Password:
Waf: Entering directory `/Users/sh1mmer/Downloads/node-v0.6.6/out'
DEST_OS: darwin
DEST_CPU: x64
Parallel Jobs: 1
Product type: program
* installing deps/uv/include/ares.h as /usr/local/include/node/ares.h
* installing deps/uv/include/ares_version.h as /usr/local/include/node/ares_version.h
* installing deps/uv/include/uv.h as /usr/local/include/node/uv.h
...
* installing out/Release/src/node_config.h as /usr/local/include/node/node_config.h
Waf: Leaving directory `/Users/sh1mmer/Downloads/node-v0.6.6/out'
'install' finished successfully (0.915s)
enki:node-v0.6.6 $</pre></div></div><p><a id="chap5_id35941591"/>If you want to install only for the local user
and avoid using the <code class="literal">sudo</code> command, you
need to run <a id="I_indexterm1_d1e672" class="indexterm"/>the <code class="literal">configure</code> script with
the <code class="literal">--prefix</code> argument to tell Node to
install somewhere other than the <a id="I_indexterm1_d1e684" class="indexterm"/><a id="I_indexterm1_d1e686" class="indexterm"/>default (<a class="xref" href="ch01.html#chap5_id35941606" title="Example 1-5. Installing Node for a local user">Example 1-5</a>).</p><div class="example"><a id="chap5_id35941606"/><p class="title">Example 1-5. Installing Node for a local user</p><div class="example-contents"><a id="chap5_id35941656"/><pre class="programlisting">enki:node-v0.6.6 $ <strong class="userinput"><code>mkdir ~/local</code></strong>
enki:node-v0.6.6 $ <strong class="userinput"><code>./configure --prefix=~/local</code></strong>
Checking for program g++ or c++ : /usr/bin/g++
Checking for program cpp : /usr/bin/cpp
...
'configure' finished successfully (0.501s)
enki:node-v0.6.6 $ make && make install
Waf: Entering directory `/Users/sh1mmer/Downloads/node-v0.6.6/out'
DEST_OS: darwin
DEST_CPU: x64
...
* installing out/Release/node as /Users/sh1mmer/local/bin/node
* installing out/Release/src/node_config.h as /Users/sh1mmer/local/include/node/...
Waf: Leaving directory `/Users/sh1mmer/Downloads/node-v0.6.6/out'
'install' finished successfully (0.747s)
enki:node-v0.6.6 $</pre></div></div></div><div class="sect1" title="First Steps in Code"><div class="titlepage"><div><div><h1 class="title"><a id="chap5_id35941671"/>First Steps in Code</h1></div></div></div><p>This section will take you through a basic Node program before we
move on to more in-depth programs.</p><div class="sect2" title="Node REPL"><div class="titlepage"><div><div><h2 class="title"><a id="chap5_id35941677"/>Node REPL</h2></div></div></div><p><a id="chap5_id35941682"/>One of the things <a id="no1.2.1" class="indexterm"/><a id="ru1.2.1" class="indexterm"/><a id="re1.2.1" class="indexterm"/><a id="rep1.2.1" class="indexterm"/><a id="rea1.2.1" class="indexterm"/>that’s often hard to understand about Node.js is that, in
addition to being a server, it’s also a runtime environment in the same
way that Perl, Python, and Ruby are. So, even though we often refer to
Node.js as “server-side JavaScript,” that doesn’t really accurately
describe what Node.js does. One of the best ways to come to grips with
Node.js is to use Node REPL (“Read-Evaluate-Print-Loop”), an interactive
Node.js programming environment. It’s great for testing out and learning
about Node.js. You can try out any of the snippets in this book using
Node REPL. In addition, because Node is a wrapper around <a id="I_indexterm1_d1e732" class="indexterm"/>V8, Node REPL is an ideal place to easily try out
JavaScript. However, when you want to run a Node program, you can use
your favorite text editor, save it in a file, and simply run <code class="literal">node filename.js</code>. REPL is a great learning and
exploration tool, but we don’t use it for production code.</p><p><a id="chap5_id35941691"/>Let’s launch Node REPL and try out a few
bits of JavaScript to warm up (<a class="xref" href="ch01.html#chap5_id35941696" title="Example 1-6. Starting Node REPL and trying some JavaScript">Example 1-6</a>).
Open up a console on your system. I’m using a Mac with a custom command
prompt, so your system might look a little different, but the commands
should be the same.</p><div class="example"><a id="chap5_id35941696"/><p class="title">Example 1-6. Starting Node REPL and trying some JavaScript</p><div class="example-contents"><a id="chap5_id35941702"/><pre class="programlisting">$Enki:~ $ <strong class="userinput"><code>node</code></strong>
> <strong class="userinput"><code>3 > 2 > 1</code></strong>
false
> <strong class="userinput"><code>true == 1</code></strong>
true
> <strong class="userinput"><code>true === 1</code></strong>
false</pre></div></div><div class="note" title="Note"><h3 class="title">Note</h3><p><a id="chap5_id35941715"/>The first line, which evaluates to
<code class="literal">false</code>, is from <a class="ulink" href="http://wtfjs.com">http://wtfjs.com</a>, a collection of weird and amusing
things about JavaScript.</p></div><p><a id="chap5_id35941723"/>Having a live programming <a id="I_indexterm1_d1e772" class="indexterm"/>environment is a really great learning tool, but you
should know a few helpful features of Node REPL to make the most of it.
It offers meta-commands, which all start with a <a id="I_indexterm1_d1e778" class="indexterm"/><a id="I_indexterm1_d1e781" class="indexterm"/>period (<code class="literal">.</code>). Thus,
<code class="literal">.help</code> shows <a id="I_indexterm1_d1e791" class="indexterm"/>the help menu, <code class="literal">.clear</code>
<a id="I_indexterm1_d1e799" class="indexterm"/>clears the current context, and <code class="literal">.exit</code> <a id="I_indexterm1_d1e806" class="indexterm"/>quits Node REPL (see <a class="xref" href="ch01.html#chap5_id35941750" title="Example 1-7. Using the metafeatures in Node REPL">Example 1-7</a>).
The most useful command is <code class="literal">.clear</code>,
which wipes out any variables or closures you have in memory without the
need to restart REPL.</p><div class="example"><a id="chap5_id35941750"/><p class="title">Example 1-7. Using the metafeatures in Node REPL</p><div class="example-contents"><a id="chap5_id35941756"/><pre class="programlisting">> <strong class="userinput"><code>console.log('Hello World');</code></strong>
Hello World
> <strong class="userinput"><code>.help</code></strong>
.clear Break, and also clear the local context.
.exit Exit the prompt
.help Show repl options
> .clear
Clearing context...
> <strong class="userinput"><code>.exit</code></strong>
Enki:~ $</pre></div></div><p><a id="chap5_id35941767"/>When using REPL, simply typing the name of a
variable will enumerate it in the shell. Node tries to do this
intelligently so a complex object won’t just be represented as a
<a id="I_indexterm1_d1e831" class="indexterm"/>simple <code class="literal">Object</code>, but
through a description that reflects what’s in the object (<a class="xref" href="ch01.html#chap5_id35941778" title="Example 1-8. Setting and enumerating objects with REPL">Example 1-8</a>). The main exception to this involves
<a id="I_indexterm1_d1e842" class="indexterm"/>functions. It’s not that REPL doesn’t have a way to
enumerate functions; it’s that functions have the tendency to be very
large. If REPL enumerated functions, a lot of output could <a id="I_indexterm1_d1e848" class="indexterm"/><a id="I_indexterm1_d1e850" class="indexterm"/><a id="I_indexterm1_d1e853" class="indexterm"/><a id="I_indexterm1_d1e855" class="indexterm"/><a id="I_indexterm1_d1e857" class="indexterm"/>scroll by.</p><div class="example"><a id="chap5_id35941778"/><p class="title">Example 1-8. Setting and enumerating objects with REPL</p><div class="example-contents"><a id="chap5_id35941783"/><pre class="programlisting">Enki:~ $ node
> myObj = {};
{}
> myObj.list = ["a", "b", "c"];
[ 'a', 'b', 'c' ]
> myObj.doThat = function(first, second, third) { console.log(first); };
[Function]
> myObj
{ list: [ 'a', 'b', 'c' ]
, doThat: [Function]
}
></pre></div></div></div><div class="sect2" title="A First Server"><div class="titlepage"><div><div><h2 class="title"><a id="chap5_id35940363"/>A First Server</h2></div></div></div><p><a id="chap5_id35940368"/>REPL gives us a <a id="no1.2.2" class="indexterm"/><a id="se1.2.2" class="indexterm"/>great tool for learning and experimentation, but the main
application of Node.js is as a server. One of the specific design goals
of Node.js is to provide a highly scalable server environment. This is
an area where Node <a id="I_indexterm1_d1e881" class="indexterm"/>differs from V8, which was described at the beginning of
this chapter. Although the V8 runtime is used in Node.js to interpret
the JavaScript, Node.js also uses a number of highly optimized libraries
to make the server efficient. In particular, the HTTP module was written
from scratch in C to provide a very fast nonblocking implementation of
HTTP. Let’s take a look at the canonical Node<a id="I_indexterm1_d1e887" class="indexterm"/> “Hello World” example using an HTTP server (<a class="xref" href="ch01.html#chap5_id35940376" title="Example 1-9. A Hello World Node.js web server">Example 1-9</a>).</p><div class="example"><a id="chap5_id35940376"/><p class="title">Example 1-9. A Hello World Node.js web server</p><div class="example-contents"><a id="chap5_id35940382"/><pre class="programlisting">var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
}).listen(8124, "127.0.0.1");
console.log('Server running at http://127.0.0.1:8124/');</pre></div></div><p><a id="chap5_id35940392"/>The first thing that this code does is
use<a id="I_indexterm1_d1e900" class="indexterm"/> <code class="literal">require</code> to include the
<a id="I_indexterm1_d1e907" class="indexterm"/>HTTP library into the program. This concept is used in
many languages, but Node uses the <a id="I_indexterm1_d1e913" class="indexterm"/>CommonJS module format, which we’ll talk about more in
<a class="xref" href="ch08.html" title="Chapter 8. Extending Node">Chapter 8</a>. The main thing to know at this point is
that the functionality in the HTTP library is now assigned to the
<code class="literal">http</code> object.</p><p><a id="chap5_id35940404"/>Next, we need an HTTP server. Unlike some
languages, such as PHP, that run inside a server such as Apache, Node
itself acts as the web server. However, that also means we have to
create it. The next line calls a factory method from the HTTP module
that creates new HTTP servers. The new HTTP server isn’t assigned to a
variable; it’s simply going to be an anonymous object in the global
scope. Instead, we use chaining to initialize the server and tell it to
listen on port <code class="literal">8124</code>.</p><p><a id="chap5_id35940424"/>When calling <code class="literal">createServer</code>, we <a id="I_indexterm1_d1e933" class="indexterm"/>passed an anonymous function as an argument. This function
is attached to the new server’s event listener for the<a id="I_indexterm1_d1e939" class="indexterm"/> <code class="literal">request</code> event. Events
are central to both JavaScript and Node. In this case, whenever there is
a new request to the web server, it will call the method we’ve passed to
deal with the request. We call these kinds of methods
<span class="emphasis"><em>callbacks</em></span> <a id="I_indexterm1_d1e952" class="indexterm"/>because whenever an event happens, we “call back” all the
methods listening for that event.</p><p><a id="chap5_id35959012"/>Perhaps a good analogy would be ordering a
book from a bookshop. When your book is in stock, they <span class="emphasis"><em>call
back</em></span> to let you know you can come and collect it. This
specific callback takes the arguments <code class="literal">req</code> for the request object and <code class="literal">res</code> for the response object.</p><p><a id="chap5_id35941812"/>Inside the function we created for the
callback, we call a couple of methods on the <code class="literal">res</code> object. These calls modify the response.
<a class="xref" href="ch01.html#chap5_id35940376" title="Example 1-9. A Hello World Node.js web server">Example 1-9</a> doesn’t use the request, but
typically you would use both the request and response objects.</p><p><a id="chap5_id35959037"/>The first thing we <span class="emphasis"><em>must</em></span>
do is set the HTTP response header<a id="I_indexterm1_d1e981" class="indexterm"/><a id="I_indexterm1_d1e986" class="indexterm"/>. We can’t send any actual response to the client without
it. The <code class="literal">res.writeHead</code> method does
this. We set the value to <code class="literal">200</code> (for
the HTTP status code “200 OK”) and pass a list of HTTP headers. In this
case, the only header we specify is <code class="literal">Content-type</code>.</p><p><a id="chap5_id35959056"/>After we’ve written the HTTP header to the
client, we can write the HTTP body. In this case, we use a single method
to both write the body and close the connection. The <code class="literal">end</code> method <a id="I_indexterm1_d1e1006" class="indexterm"/>closes the HTTP connection, but since we also passed it a
string, it will send that to the client before it closes the
connection.</p><p><a id="chap5_id35941843"/>Finally, the last line of our example uses
the <code class="literal">console.log</code>. This <a id="I_indexterm1_d1e1017" class="indexterm"/>simply prints information to <code class="literal">stdout</code>, much like the browser counterpart
supported by Firebug and Web Inspector.</p><p><a id="chap5_id35941854"/>Let’s run this with Node.js on the console
and see what we get (<a class="xref" href="ch01.html#chap5_id35941858" title="Example 1-10. Running the Hello World example">Example 1-10</a>).</p><div class="example"><a id="chap5_id35941858"/><p class="title">Example 1-10. Running the Hello World example</p><div class="example-contents"><a id="chap5_id35941863"/><pre class="programlisting">Enki:~ $ <strong class="userinput"><code>node</code></strong>
> var http = require('http');
> http.createServer(function (req, res) {
... res.writeHead(200, {'Content-Type': 'text/plain'});
... res.end('Hello World\n');
... }).listen(8124, "127.0.0.1");
> console.log('Server running at http://127.0.0.1:8124/');
Server running at http://127.0.0.1:8124/
node></pre></div></div><p><a id="chap5_id35941874"/>Here we start a Node REPL and type in the
code from the sample (we’ll forgive you for pasting it from the
website). Node REPL accepts the code, using <code class="literal">...</code> to indicate that you haven’t completed the
statement and should continue entering it. When we run the <code class="literal">console.log</code> line, Node REPL prints
out <code class="literal">Server running at
http://127.0.0.1:8124/</code>. Now we are ready to call our Hello
World example in a web browser (<a class="xref" href="ch01.html#first_server_output" title="Figure 1-1. Viewing the Hello World web server from a browser">Figure 1-1</a>).</p><div class="figure"><a id="first_server_output"/><div class="figure-contents"><div class="mediaobject"><a id="I_mediaobject1_d1e1058"/><img src="httpatomoreillycomsourceoreillyimages1137975.png.jpg" alt="Viewing the Hello World web server from a browser"/></div></div><p class="title">Figure 1-1. Viewing the Hello World web server from a browser</p></div><p><a id="chap5_id35941912"/>It works! Although this isn’t exactly a
stunning demo, it is notable that we got Hello World working in six
lines of code. Not that we would recommend that style of coding, but we
are starting to get somewhere. In the next chapter, we’ll look at a lot
more code, but first let’s think about why Node is <a id="I_indexterm1_d1e1065" class="indexterm"/><a id="I_indexterm1_d1e1067" class="indexterm"/>how it is.</p></div></div><div class="sect1" title="Why Node?"><div class="titlepage"><div><div><h1 class="title"><a id="I_sect11_d1e1070"/>Why Node?</h1></div></div></div><p><a id="chap2_id35941320"/>In writing this <a id="no1.3" class="indexterm"/>book, we’ve been acutely aware of how new Node.js is. Many
platforms take years to find adoption, and yet there’s a level of
excitement around Node.js that we’ve never seen before in such a young
platform. We hope that by looking at the reasons other people are getting
so excited about Node.js, you will find features that also resonate with
you. By looking at Node.js’s strengths, we can find the places where it is
most applicable. This section looks at the factors that have come together
to create a space for Node.js and discusses the reasons why it’s become so
popular in such a short time.</p><div class="sect2" title="High-Performance Web Servers"><div class="titlepage"><div><div><h2 class="title"><a id="id539414"/>High-Performance Web Servers</h2></div></div></div><p>When we first started writing <a id="I_indexterm1_d1e1086" class="indexterm"/><a id="I_indexterm1_d1e1091" class="indexterm"/>web applications more than 10 years ago, the Web was much
smaller. Sure, we had the dot-com bubble, but the sheer volume of people
on the Internet was considerably lower, and the sites we made were much
less ambitious. Fast-forward to today, and we have the advent of Web 2.0
and widely available Internet connections on cell phones. So much more
is expected of us as developers. Not only are the features we need to
deliver more complex, more interactive, and more real, but there are
also many more people using them more often and from more devices than
ever before. This is a pretty steep challenge. While hardware continues
to improve, we also need to make improvements to our software
development practices to support such demands. If we kept just buying
hardware to support ever-increasing features or users, it wouldn’t be
very cost-effective.</p><p>Node is an attempt to solve this problem by introducing the
architecture called <span class="emphasis"><em>event-driven computing</em></span> to the
programming space for web servers. As it turns out, Node isn’t the first
platform to do this, but it is by far the most successful, and we would
argue that it is the easiest to use. We are going to talk about
event-driven programming in a lot more detail later in this book, but
let’s go through a quick intro here. Imagine you connect to a web server
to get a web page. The time to reach that web server is probably 100ms
or so over a reasonable DSL connection. When you connect to a typical
web server, it creates a new instance of a program on the server that
represents your request. That program runs from the top to the bottom
(following all of the function calls) to provide your web page. This
means that the server has to allocate a fixed amount of memory to that
request until it is totally finished, including the 100ms+ to send the
data back to you. Node doesn’t work that way. Instead, Node keeps all
users in a single program. Whenever Node has to do something slow, like
wait for a confirmation that you got your data (so it can mark your
request as finished), it simply moves on to another user. We’re glossing
over the details a bit, but this means Node is much more efficient with
memory than traditional servers and can keep providing a very fast
response time with lots and lots of concurrent users. This is a huge
win. This approach is one of the main reasons people like Node.</p></div><div class="sect2" title="Professionalism in JavaScript"><div class="titlepage"><div><div><h2 class="title"><a id="chap2_id35941328"/>Professionalism in JavaScript</h2></div></div></div><p><a id="chap2_id35941334"/>Another reason people like <a id="I_indexterm1_d1e1107" class="indexterm"/>Node is JavaScript. JavaScript was created by <a id="I_indexterm1_d1e1113" class="indexterm"/>Brendan Eich in 1995 to be a simple scripting language for
use in web pages on the Netscape browser platform. Surprisingly, almost
since its inception JavaScript has been used in nonbrowser settings.
Some of the early Netscape server products supported JavaScript (known
then as LiveScript) as a server-side scripting language. Although
server-side JavaScript didn’t really catch on then, that certainly
wasn’t true for the exploding browser market. On the Web, JavaScript
competed with Microsoft’s VBScript to provide programming functionality
in web pages. It’s hard to say <a id="I_indexterm1_d1e1117" class="indexterm"/><a id="I_indexterm1_d1e1122" class="indexterm"/>why JavaScript won, but perhaps Microsoft allowing
JavaScript in Internet Explorer did it,<sup>[<a id="id761867" href="#ftn.id761867" class="footnote">1</a>]</sup> or perhaps it was the JavaScript language itself, but win
it did. This meant by the early 2000s, JavaScript had emerged as
<span class="emphasis"><em>the</em></span> web language—not just the first choice, but the
<span class="emphasis"><em>only</em></span> choice for programming with HTML in
browsers.</p><p><a id="chap2_id35941358"/>What does this have to do with Node.js?
Well, the important thing to remember is that when the AJAX revolution
happened and the Web became big business (think Yahoo!, Amazon, Google,
etc.), the only choice for the “J” in AJAX was JavaScript. There simply
wasn’t an alternative. As a result, a whole industry needed an awful lot
of JavaScript programmers, and really good ones at that, rather fast.
The emergence of the Web as a serious platform and JavaScript as its
programming language meant that we, as JavaScript programmers, needed to
shape up. We can equate the change in JavaScript as the second or third
programming language of a programmer to the change in perception of its
importance. We started to get emerging experts who led the charge in
making JavaScript respectable.</p><p><a id="chap2_id35941367"/>Arguably at the head of this movement was
<a id="I_indexterm1_d1e1143" class="indexterm"/>Douglas Crockford. His popular articles and videos on
JavaScript have helped many programmers discover that inside this
much-maligned language there is a lot of beauty. Most programmers
working with JavaScript spent the majority of their time working with
the browser implementation of the W3C DOM API for manipulating HTML or
XML documents. Unfortunately, the DOM is probably not the prettiest API
ever conceived, but worse, its various implementations in the browsers
are inconsistent and incomplete. No wonder that for a decade after its
release JavaScript was not thought of as a “proper” language by so many
programmers. More recently, Douglas’s work on “the good parts” of
JavaScript have helped create a movement of advocates of the language
who recognize that it has a lot going for it, despite the warts.</p><p><a id="chap2_id35941378"/>In 2012, we now have a proliferation of
JavaScript experts advocating well-written, performant, maintainable
JavaScript code. People such as Douglas Crockford, <a id="I_indexterm1_d1e1149" class="indexterm"/>Dion Almaer, <a id="I_indexterm1_d1e1153" class="indexterm"/>Peter Paul Koch (PPK), <a id="I_indexterm1_d1e1157" class="indexterm"/>John Resig, <a id="I_indexterm1_d1e1161" class="indexterm"/>Alex Russell, <a id="I_indexterm1_d1e1165" class="indexterm"/>Thomas Fuchs, and many more have provided research,
advice, tools, and primarily libraries that have allowed thousands of
professional JavaScript programmers worldwide to practice their trade
with a spirit of excellence. Libraries such as jQuery, YUI, Dojo,
Prototype, Mootools, Sencha, and many others are now used daily by
thousands of people and deployed on millions of websites. It is in this
environment—where JavaScript is not only accepted, but widely used and
celebrated—that a platform larger than the Web makes sense. When so many
programmers know JavaScript, its ubiquity is a distinct
advantage.</p><p><a id="chap2_id35941390"/>When a roomful of web programmers is asked
what languages they use, Java and PHP are very popular, Ruby is probably
the next most popular these days (or at least closely tied with Python),
and Perl still has a huge following. However, almost without exception,
anyone who does any programming for the Web has programmed in JavaScript. Although backend languages are
fractured in-browser, programming is united by the necessities of
deployment. Various browsers and browser plug-ins allow the use of other
languages, but they simply aren’t universal enough for the Web. So here
we are with a single, universal web language. How can we get it on the
server?</p></div><div class="sect2" title="Browser Wars 2.0"><div class="titlepage"><div><div><h2 class="title"><a id="chap2_id35941400"/>Browser Wars 2.0</h2></div></div></div><p><a id="chap2_id35941405"/>Fairly early in the <a id="I_indexterm1_d1e1179" class="indexterm"/><a id="I_indexterm1_d1e1184" class="indexterm"/>days of the Web, we had the infamous <span class="emphasis"><em>browser
wars</em></span>. Internet Explorer and Netscape competed viciously on
web features, adding various incompatible programmatic features to their
own browser and not supporting the features in the other browser. For
those of us who programmed for the Web, this was the cause of much
anguish because it made web programming really tiresome. Internet
Explorer more or less emerged as the winner of that round and became the
dominant browser. Fast-forward a
few years, and Internet Explorer has been languishing at version 6, and
a new contender, Firefox, emerges from the remnants of Netscape. Firefox
kicks off a resurgence in browsers, followed by WebKit (Safari) and then
Chrome. Most interesting about this current trend is the resurgence of
competition in the browser market.</p><p><a id="chap2_id35941418"/>Unlike the first iteration of the browser
wars, today’s browsers compete on two fronts: adhering to the standards
that emerged after the previous browser war, and performance. As
websites have become more complex, users want the fastest experience
possible. This has meant that browsers not only need to support the web
standards well, allowing developers to optimize, but also to do a little
optimization of their own. With JavaScript as a core component of Web
2.0, AJAX websites have become part of the battleground.</p><p><a id="chap2_id35941426"/>Each browser has its own JavaScript runtime:
Spider Monkey for Firefox, Squirrel Fish Extreme for Safari, Karakan for
Opera, and finally V8 for Chrome. As these runtimes compete on
performance, it creates an environment of innovation for JavaScript. And
in order to differentiate their browsers, vendors are going to great
lengths to make them as fast as <a id="I_indexterm1_d1e1200" class="indexterm"/>possible.</p></div></div><div class="footnotes"><br/><hr/><div class="footnote"><p><sup>[<a id="ftn.id761867" href="#id761867" class="para">1</a>] </sup>Internet Explorer doesn’t actually support JavaScript or
ECMAScript; it supports a language variety called JScript. In recent
years, JScript has fully supported the ECMAScript 3 standard and has
some ECMAScript 5 support. However, JScript also implements
proprietary extensions in the same way that Mozilla JavaScript does
and has features that ECMAScript does not.</p></div></div></div></body></html>