Skip to content
Newer
Older
100644 782 lines (541 sloc) 34.3 KB
2a420a7 @tj No longer gitignoring html
tj authored Aug 31, 2010
1 <html>
2 <head>
3 <title>Mastering Node</title>
4 <style>
5 body {
69df60f @tj Added crappy default theme
tj authored Aug 31, 2010
6 font: 14px/1.4 "Lucida Grande", "Helvetica Neue", Arial, sans-serif;
2a420a7 @tj No longer gitignoring html
tj authored Aug 31, 2010
7 padding: 50px 180px;
8 }
69df60f @tj Added crappy default theme
tj authored Aug 31, 2010
9 h1 {
10 padding-left: 5px;
11 border-bottom: 3px solid #eee;
12 }
13 pre {
14 margin: 15px 0;
15 padding: 15px;
16 border: 1px solid #eee;
17 }
18 a {
19 color: #00aaff;
20 }
09d5c0f @tj Fixed head markup
tj authored Sep 2, 2010
21 </style>
22 </head>
23 <body><div class='mp'>
2a420a7 @tj No longer gitignoring html
tj authored Aug 31, 2010
24 <h1>Mastering Node</h1>
25 <p><a href="http://nodejs.org/">Node</a> is an exciting new platform developed by <em>Ryan Dahl</em>, allowing JavaScript developers to create extremely high performance servers by leveraging <a href="http://code.google.com/p/v8/">Google's V8</a> JavaScript engine, and asynchronous I/O. In <em>Mastering Node</em> we will discover how to write high concurrency web servers, utilizing the CommonJS module system, node's core libraries, third party modules, high level web development and more.</p>
26
27 </div>
28 <div class='mp'>
29 <h1>Installing Node</h1>
fa384c9 @tj Regenerated book
tj authored Sep 7, 2010
30 <p>In this chapter we will be looking at the installation and compilation of node. Although there are several ways we may install node, we will be looking at <a href="http://github.com/mxcl/homebrew">homebrew</a>, <a href="http://github.com/visionmedia/ndistro">nDistro</a>, and the most flexible method, of course - compiling from source.</p>
2a420a7 @tj No longer gitignoring html
tj authored Aug 31, 2010
31
32 <h3 id="Homebrew">Homebrew</h3>
33
34 <p>Homebrew is a package management system for <em>OSX</em> written in Ruby, is extremely well adopted, and easy to use. To install node via the <code>brew</code> executable simply run:</p>
35
36 <pre><code>$ brew install node.js
37 </code></pre>
38
39 <h2 id="nDistro">nDistro</h2>
40
41 <p><a href="http://github.com/visionmedia/ndistro">nDistro</a> is a distribution toolkit for node, which allows creation and installation of node distros within seconds. An <em>nDistro</em> is simply a dotfile named <em>.ndistro</em> which defines
42 module and node binary version dependencies. In the example
43 below we specify the node binary version <em>0.1.102</em>, as well as
44 several 3rd party modules.</p>
45
46 <pre><code>node 0.1.102
47 module senchalabs connect
48 module visionmedia express 1.0.0beta2
49 module visionmedia connect-form
50 module visionmedia connect-redis
51 module visionmedia jade
52 module visionmedia ejs
53 </code></pre>
54
55 <p>Any machine that can run a shell script can install distributions, and keeps dependencies defined to a single directory structure, making it easy to maintain an deploy. nDistro uses <a href="http://github.com/visionmedia/nodes">pre-compiled node binaries</a> making them extremely fast to install, and module tarballs which are fetched from <a href="http://github.com">GitHub</a> via <em>wget</em> or <em>curl</em> (auto detected).</p>
56
57 <p>To get started we first need to install nDistro itself, below we <em>cd</em> to our bin directory of choice, <em>curl</em> the shell script, and pipe the response to <em>sh</em> which will install nDistro to the current directory:</p>
58
59 <pre><code>$ cd /usr/local/bin &amp;&amp; curl http://github.com/visionmedia/ndistro/raw/master/install | sh
60 </code></pre>
61
62 <p>Next we can place the contents of our example in <em>./.ndistro</em>, and execute <em>ndistro</em> with no arguments, prompting the program to load the config, and start installing:</p>
63
64 <pre><code>$ ndistro
65 </code></pre>
66
fa384c9 @tj Regenerated book
tj authored Sep 7, 2010
67 <p>Installation of the example took less than 17 seconds on my machine, and outputs the following <em>stdout</em> indicating success. Not bad for an entire stack!</p>
2a420a7 @tj No longer gitignoring html
tj authored Aug 31, 2010
68
69 <pre><code>... installing node-0.1.102-i386
70 ... installing connect
71 ... installing express 1.0.0beta2
72 ... installing bin/express
73 ... installing connect-form
74 ... installing connect-redis
75 ... installing jade
76 ... installing bin/jade
77 ... installing ejs
78 ... installation complete
79 </code></pre>
80
81 <h2 id="Building-From-Source">Building From Source</h2>
82
83 <p>To build and install node from source, we first need to obtain the code. The first method of doing so is
84 via <code>git</code>, if you have git installed you can execute:</p>
85
86 <pre><code>$ git clone http://github.com/ry/node.git &amp;&amp; cd node
87 </code></pre>
88
89 <p>For those without <em>git</em>, or who prefer not to use it, we can also download the source via <em>curl</em>, <em>wget</em>, or similar:</p>
90
91 <pre><code>$ curl -# http://nodejs.org/dist/node-v0.1.99.tar.gz &gt; node.tar.gz
92 $ tar -zxf node.tar.gz
93 </code></pre>
94
95 <p>Now that we have the source on our machine, we can run <code>./configure</code> which discovers which libraries are available for node to utilize such as <em>OpenSSL</em> for transport security support, C and C++ compilers, etc. <code>make</code> which builds node, and finally <code>make install</code> which will install node.</p>
96
97 <pre><code>$ ./configure &amp;&amp; make &amp;&amp; make install
98 </code></pre>
99
100 </div>
101 <div class='mp'>
102 <h1>CommonJS Module System</h1>
103 <p><a href="http://commonjs.org">CommonJS</a> is a community driven effort to standardize packaging of JavaScript libraries, known as <em>modules</em>. Modules written which comply to this standard provide portability between other compliant frameworks such as narwhal, and in some cases even browsers.</p>
104
105 <p>Although this is ideal, in practice modules are often not portable due to relying on apis that are currently only provided by, or are tailored to node specifically. As the framework matures, and additional standards emerge our modules will become more portable.</p>
106
107 <h2 id="Creating-Modules">Creating Modules</h2>
108
fa384c9 @tj Regenerated book
tj authored Sep 7, 2010
109 <p>Let's create a utility module named <em>utils</em>, which will contain a <code>merge()</code> function to copy the properties of one object to another. Typically in a browser, or environment without CommonJS module support, this may look similar to below, where <code>utils</code> is a global variable.</p>
2a420a7 @tj No longer gitignoring html
tj authored Aug 31, 2010
110
111 <pre><code>var utils = {};
112 utils.merge = function(obj, other) {};
113 </code></pre>
114
115 <p>Although namespacing can lower the chance of collisions, it can still become an issue, and when further namespacing is applied it can look flat-out silly. CommonJS modules aid in removing this issue by "wrapping" the contents of a JavaScript file with a closure similar to what is shown below, however more pseudo globals are available to the module in addition to <code>exports</code>, <code>require</code>, and <code>module</code>. The <code>exports</code> object is then returned when a user invokes <code>require('utils')</code>.</p>
116
117 <pre><code>var module = { exports: {}};
118 (function(module, exports){
119 function merge(){};
120 exports.merge = merge;
121 })(module, module.exports);
122 </code></pre>
123
124 <p>First create the file <em>./utils.js</em>, and define the <code>merge()</code> function as seen below. The implied anonymous wrapper function shown above allows us to seemingly define globals, however these are not accessible until exported.</p>
125
126 <pre><code> function merge(obj, other) {
127 var keys = Object.keys(other);
128 for (var i = 0, len = keys.length; i &lt; len; ++i) {
129 var key = keys[i];
130 obj[key] = other[key];
131 }
132 return obj;
133 };
134
135 exports.merge = merge;
136 </code></pre>
137
138 <p>The typical pattern for public properties is to simply define them
139 on the <code>exports</code> object like so:</p>
140
141 <pre><code>exports.merge = function(obj, other) {
142 var keys = Object.keys(other);
143 for (var i = 0, len = keys.length; i &lt; len; ++i) {
144 var key = keys[i];
145 obj[key] = other[key];
146 }
147 return obj;
148 };
149 </code></pre>
150
151 <p>Next we will look at utilizing out new module in other libraries.</p>
152
153 <h2 id="Requiring-Modules">Requiring Modules</h2>
154
155 <p>There are four main ways to require a module in node, first is the <em>synchronous</em> method, which simply returns the module's exports, second is the <em>asynchronous</em> method which accepts a callback, third is the <em>asynchronous http</em> method which can load remote modules, and lastly is requiring of shared libraries or "node addons" which we will cover later.</p>
156
157 <p>To get started create a second file named <em>./app.js</em> with the code shown below. The first line <code>require('./utils')</code> fetches the contents of <em>./utils.js</em> and returns the <code>exports</code> of which we later utilize our <code>merge()</code> method and display the results of our merged object using <code>console.dir()</code>.</p>
158
159 <pre><code>var utils = require('./utils');
160
161 var a = { one: 1 };
162 var b = { two: 2 };
163 utils.merge(a, b);
164 console.dir(a);
165 </code></pre>
166
167 <p>Core modules such as the <em>sys</em> which are bundled with node can be required without a path, such as <code>require('sys')</code>, however 3rd-party modules will iterate the <code>require.paths</code> array in search of a module matching the given path. By default <code>require.paths</code> includes <em>~/.node_libraries</em>, so if <em>~/.node_libraries</em>/utils.js_ exists we may simply <code>require('utils')</code>, instead of our relative example <code>require('./utils')</code> shown above.</p>
168
169 <p>Node also supports the concept of <em>index</em> JavaScript files. To illustrate this example lets create a <em>math</em> module that will provide the <code>math.add()</code>, and <code>math.sub()</code> methods. For organizational purposes we will keep each method in their respective <em>./math/add.js</em> and <em>./math/sub.js</em> files. So where does <em>index.js</em> come into play? we can populate <em>./math/index.js</em> with the code shown below, which is used when <code>require('./math')</code> is invoked, which is conceptually identical to invoking <code>require('./math/index')</code>.</p>
170
171 <pre><code>module.exports = {
172 add: require('./add'),
173 sub: require('./sub')
174 };
175 </code></pre>
176
177 <p>The contents of <em>./math/add.js</em> show us a new technique, here we use <code>module.exports</code> instead of <code>exports</code>. Previously mentioned was the fact that <code>exports</code> is not the only object exposed to the module file when evaluated, we also have access to <code>__dirname</code>, <code>__filename</code>, and <code>module</code> which represents the current module. Here we simply define the module export object to a new object, which happens to be a function.</p>
178
179 <pre><code>module.exports = function add(a, b){
180 return a + b;
181 };
182 </code></pre>
183
184 <p>This technique is usually only helpful when your module has one aspect that it wishes to expose, be it a single function, constructor, string, etc. Below is an example of how we could provide the <code>Animal</code> constructor:</p>
185
186 <pre><code>exports.Animal = function Animal(){};
187 </code></pre>
188
189 <p>which can then be utilized as shown:</p>
190
191 <pre><code>var Animal = require('./animal').Animal;
192 </code></pre>
193
194 <p>if we change our module slightly, we can remove <code>.Animal</code>:</p>
195
196 <pre><code>module.exports = function Animal(){};
197 </code></pre>
198
199 <p>which can now be used without the property:</p>
200
201 <pre><code>var Animal = require('./animal');
202 </code></pre>
203
204 <h2 id="Require-Paths">Require Paths</h2>
205
206 <p>We talked about <code>require.paths</code>, the <code>Array</code> utilized by node's module system in order to discover modules. By default node checks the following directories for modules:</p>
207
208 <ul>
209 <li><code>&lt;node binary></code>/../../lib/node</li>
210 <li><strong>$HOME</strong>/.node_libraries</li>
211 <li><strong>$NODE_PATH</strong></li>
212 </ul>
213
214
215 <p>The <strong>NODE_PATH</strong> environment variable is much like <strong>PATH</strong>, as it allows several paths delimited by the colon (<code>:</code>) character.</p>
216
217 <h3 id="Runtime-Manipulation">Runtime Manipulation</h3>
218
219 <p>Since <code>require.paths</code> is just an array, we can manipulate it at runtime in order to expose libraries. In our previous example we defined the libraries <em>./math/{add,sub}.js</em>, in which we would typically <code>require('./math')</code> or <code>require('./math/add')</code> etc. Another approach is to prepend or "unshift" a directory onto <code>require.paths</code> as shown below, after which we can simply <code>require('add')</code> since node will iterate the paths in order to try and locate the module.</p>
220
221 <pre><code>require.paths.unshift(__dirname + '/math');
222
223 var add = require('add'),
224 sub = require('sub');
225
226 console.log(add(1,2));
227 console.log(sub(1,2));
228 </code></pre>
229
230 <h2 id="Pseudo-Globals">Pseudo Globals</h2>
231
232 <p>As mentioned above, modules have several pseudo globals available to them, these are as follows:</p>
233
234 <ul>
235 <li><code>require</code> the require function itself</li>
236 <li><code>module</code> the current <code>Module</code> instance</li>
237 <li><code>exports</code> the current module's exported properties</li>
238 <li><code>__filename</code> absolute path to the current module's file</li>
239 <li><code>__dirname</code> absolute path to the current module's directory</li>
240 </ul>
241
242
243 <h3 id="require-">require()</h3>
244
245 <p>Although not obvious at first glance, the <code>require()</code> function is actually
246 re-defined for the current module, and calls an internal function <code>loadModule</code> with a reference to the current <code>Module</code> to resolve relative paths and to populate <code>module.parent</code>.</p>
247
248 <h3 id="module">module</h3>
249
250 <p>When we <code>require()</code> a module, typically we only deal with the module's <code>exports</code>, however the <code>module</code> variable references the current module's <code>Module</code> instance. This is why the following is valid, as we may re-assign the module's <code>exports</code> to any object, even something trivial like a string:</p>
251
252 <pre><code>// css.js
253 module.exports = 'body { background: blue; }';
254 </code></pre>
255
256 <p>To obtain this string we would simply <code>require('./css')</code>. The <code>module</code> object also contains these useful properties:</p>
257
258 <ul>
259 <li><code>id</code> the module's id, consisting of a path. Ex: <code>./app</code></li>
260 <li><code>parent</code> the parent <code>Module</code> (which required this one) or <code>undefined</code></li>
261 <li><code>filename</code> absolute path to the module</li>
262 <li><code>moduleCache</code> an object containing references to all cached modules</li>
263 </ul>
264
265
266 <h2 id="Asynchronous-Require">Asynchronous Require</h2>
267
268 <p>Node provides us with an asynchronous version of <code>require()</code>, aptly named <code>require.async()</code>. Below is the sample example previously shown for our <em>utils</em> module, however non blocking. <code>require.async()</code> accepts a callback of which the first parameter <code>err</code> is <code>null</code> or an instanceof <code>Error</code>, and then the module exports. Passing the error (if there is one) as the first argument is an extremely common idiom in node for async routines.</p>
269
270 <pre><code>require.async('./utils', function(err, utils){
271 console.dir(utils.merge({ foo: 'bar' }, { bar: 'baz' }));
272 });
273 </code></pre>
274
275 <h2 id="Requiring-Over-HTTP">Requiring Over HTTP</h2>
276
277 <p>Asynchronous requires in node also have the added bonus of allowing module loading via <strong>HTTP</strong> and <strong>HTTPS</strong>.
278 To require a module via http all we have to do is pass a valid url as shown in the <em>sass</em> to <em>css</em> compilation example below:</p>
279
280 <pre><code>var sassUrl = 'http://github.com/visionmedia/sass.js/raw/master/lib/sass.js',
281 sassStr = ''
282 + 'body\n'
283 + ' a\n'
284 + ' :color #eee';
285
286 require.async(sassUrl, function(err, sass){
287 var str = sass.render(sassStr);
288 console.log(str);
289 });
290 </code></pre>
291
292 <p>Outputs:</p>
293
294 <pre><code>body a {
295 color: #eee;}
296 </code></pre>
297
298 <h2 id="Registering-Module-Compilers">Registering Module Compilers</h2>
299
fa384c9 @tj Regenerated book
tj authored Sep 7, 2010
300 <p>Another cool feature that node provides us is the ability to register compilers for a specific file extension. A good example of this is the CoffeeScript language, which is a ruby/python inspired language compiling to vanilla JavaScript. By using <code>require.registerExtension()</code> we can have node compile CoffeeScript to JavaScript in an automated fashion.</p>
2a420a7 @tj No longer gitignoring html
tj authored Aug 31, 2010
301
fa384c9 @tj Regenerated book
tj authored Sep 7, 2010
302 <p>To illustrate its usage, let's create a small (and useless) Extended JavaScript language, or "ejs" for our example which will live at <em>./compiler/example.ejs</em>, its syntax will look like this:</p>
2a420a7 @tj No longer gitignoring html
tj authored Aug 31, 2010
303
304 <pre><code>::min(a, b) a &lt; b ? a : b
305 ::max(a, b) a &gt; b ? a : b
306 </code></pre>
307
308 <p>which will be compiled to:</p>
309
310 <pre><code>exports.min = function min(a, b) { return a &lt; b ? a : b }
311 exports.max = function max(a, b) { return a &gt; b ? a : b }
312 </code></pre>
313
fa384c9 @tj Regenerated book
tj authored Sep 7, 2010
314 <p>First let's create the module that will actually be doing the ejs to JavaScript compilation. In this example it is located at <em>./compiler/extended.js</em>, and exports a single method named <code>compile()</code>. This method accepts a string, which is the raw contents of what node is requiring, transformed to vanilla JavaScript via regular expressions.</p>
2a420a7 @tj No longer gitignoring html
tj authored Aug 31, 2010
315
316 <pre><code>exports.compile = function(str){
317 return str
318 .replace(/(\w+)\(/g, '$1 = function $1(')
319 .replace(/\)(.+?)\n/g, '){ return $1 }\n')
320 .replace(/::/g, 'exports.');
321 };
322 </code></pre>
323
324 <p>Next we have to "register" the extension to assign out compiler. As previously mentioned our compiler lives at <em>./compiler/extended.js</em> so we are requiring it in, and passing the <code>compile()</code> method to <code>require.registerExtension()</code> which simply expects a function accepting a string, and returning a string of JavaScript.</p>
325
326 <pre><code>require.registerExtension('.ejs', require('./compiler/extended').compile);
327 </code></pre>
328
329 <p>Now when we require our example, the ".ejs" extension is detected, and will pass the contents through our compiler, and everything works as expected.</p>
330
331 <pre><code>var example = require('./compiler/example');
332 console.dir(example)
333 console.log(example.min(2, 3));
334 console.log(example.max(10, 8));
335
336 // =&gt; { min: [Function], max: [Function] }
337 // =&gt; 2
338 // =&gt; 10
339 </code></pre>
340
341 </div>
342 <div class='mp'>
343 <h1>Globals</h1>
344 <p> As we have learnt node's module system discourages the use of globals, however node provides a few important globals for use to utilize. The first and most important is the <code>process</code> global which exposes process manipulation such as signalling, exiting, the process id (pid), and more. Other globals help drive to be similar to other familiar JavaScript environments such as the browser, by providing a <code>console</code> object.</p>
345
346 <h2 id="console">console</h2>
347
fa384c9 @tj Regenerated book
tj authored Sep 7, 2010
348 <p>The <code>console</code> object contains several methods which are used to output information to <em>stdout</em> or <em>stderr</em>. Let's take a look at what each method does.</p>
2a420a7 @tj No longer gitignoring html
tj authored Aug 31, 2010
349
350 <h3 id="console-log-">console.log()</h3>
351
352 <p>The most frequently used console method is <code>console.log()</code> simply writing to <em>stdout</em> with a line feed (<code>\n</code>). Currently aliased as <code>console.info()</code>.</p>
353
354 <pre><code>console.log('wahoo');
355 // =&gt; wahoo
356
357 console.log({ foo: 'bar' });
358 // =&gt; [object Object]
359 </code></pre>
360
361 <h3 id="console-error-">console.error()</h3>
362
363 <p>Identical to <code>console.log()</code>, however writes to <em>stderr</em>. Aliased as <code>console.warn()</code> as well.</p>
364
365 <pre><code>console.error('database connection failed');
366 </code></pre>
367
368 <h3 id="console-dir-">console.dir()</h3>
369
370 <p>Utilizes the <em>sys</em> module's <code>inspect()</code> method to pretty-print the object to
371 <em>stdout</em>.</p>
372
373 <pre><code>console.dir({ foo: 'bar' });
374 // =&gt; { foo: 'bar' }
375 </code></pre>
376
377 <h3 id="console-assert-">console.assert()</h3>
378
379 <p>Asserts that the given expression is truthy, or throws an exception.</p>
380
381 <pre><code>console.assert(connected, 'Database connection failed');
382 </code></pre>
383
384 <h2 id="process">process</h2>
385
386 <p>The <code>process</code> object is plastered with goodies, first we will take a look
387 at some properties that provide information about the node process itself.</p>
388
389 <h3 id="process-version">process.version</h3>
390
391 <p>The version property contains the node version string, for example "v0.1.103".</p>
392
393 <h3 id="process-installPrefix">process.installPrefix</h3>
394
395 <p>Exposes the installation prefix, in my case "<em>/usr/local</em>", as node's binary was installed to "<em>/usr/local/bin/node</em>".</p>
396
397 <h3 id="process-execPath">process.execPath</h3>
398
399 <p>Path to the executable itself "<em>/usr/local/bin/node</em>".</p>
400
401 <h3 id="process-platform">process.platform</h3>
402
403 <p>Exposes a string indicating the platform you are running on, for example "darwin".</p>
404
405 <h3 id="process-pid">process.pid</h3>
406
407 <p>The process id.</p>
408
409 <h3 id="process-cwd-">process.cwd()</h3>
410
411 <p>Returns the current working directory, for example:</p>
412
413 <pre><code>cd ~ &amp;&amp; node
414 node&gt; process.cwd()
415 "/Users/tj"
416 </code></pre>
417
418 <h3 id="process-chdir-">process.chdir()</h3>
419
420 <p>Changes the current working directory to the path passed.</p>
421
422 <pre><code>process.chdir('/foo');
423 </code></pre>
424
425 <h3 id="process-getuid-">process.getuid()</h3>
426
427 <p>Returns the numerical user id of the running process.</p>
428
429 <h3 id="process-setuid-">process.setuid()</h3>
430
431 <p>Sets the effective user id for the running process. This method accepts both a numerical id, as well as a string. For example both <code>process.setuid(501)</code>, and <code>process.setuid('tj')</code> are valid.</p>
432
433 <h3 id="process-getgid-">process.getgid()</h3>
434
435 <p>Returns the numerical group id of the running process.</p>
436
437 <h3 id="process-setgid-">process.setgid()</h3>
438
439 <p>Similar to <code>process.setuid()</code> however operates on the group, also accepting a numerical value or string representation. For example <code>process.setgid(20)</code> or <code>process.setgid('www')</code>.</p>
440
441 <h3 id="process-env">process.env</h3>
442
443 <p>An object containing the user's environment variables, for example:</p>
444
445 <pre><code>{ PATH: '/Users/tj/.gem/ruby/1.8/bin:/Users/tj/.nvm/current/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/X11/bin'
446 , PWD: '/Users/tj/ebooks/masteringnode'
447 , EDITOR: 'mate'
448 , LANG: 'en_CA.UTF-8'
449 , SHLVL: '1'
450 , HOME: '/Users/tj'
451 , LOGNAME: 'tj'
452 , DISPLAY: '/tmp/launch-YCkT03/org.x:0'
453 , _: '/usr/local/bin/node'
454 , OLDPWD: '/Users/tj'
455 }
456 </code></pre>
457
458 <h3 id="process-argv">process.argv</h3>
459
460 <p>When executing a file with the <code>node</code> executable <code>process.argv</code> provides access to the argument vector, the first value being the node executable, second being the filename, and remaining values being the arguments passed.</p>
461
462 <p>For example our source file <em>./src/process/misc.js</em> can be executed by running:</p>
463
464 <pre><code>$ node src/process/misc.js foo bar baz
465 </code></pre>
466
467 <p>in which we call <code>console.dir(process.argv)</code>, outputting the following:</p>
468
469 <pre><code>[ 'node'
470 , '/Users/tj/EBooks/masteringnode/src/process/misc.js'
471 , 'foo'
472 , 'bar'
473 , 'baz'
474 ]
475 </code></pre>
476
477 <h3 id="process-exit-">process.exit()</h3>
478
479 <p>The <code>process.exit()</code> method is synonymous with the C function <code>exit()</code>, in which a exit code > 0 is passed indicating failure, or 0 to indicate success. When invoked the <em>exit</em> event is emitted, allowing a short time for arbitrary processing to occur before <code>process.reallyExit()</code> is called with the given status code.</p>
480
481 <h3 id="process-on-">process.on()</h3>
482
483 <p>The process itself is an <code>EventEmitter</code>, allowing you to do things like listen for uncaught exceptions, via the <em>uncaughtException</em> event:</p>
484
485 <pre><code>process.on('uncaughtException', function(err){
486 console.log('got an error: %s', err.message);
487 process.exit(1);
488 });
489
490 setTimeout(function(){
491 throw new Error('fail');
492 }, 100);
493 </code></pre>
494
495 <h3 id="process-kill-">process.kill()</h3>
496
497 <p><code>process.kill()</code> method sends the signal passed to the given <em>pid</em>, defaulting to <strong>SIGINT</strong>. In our example below we send the <strong>SIGTERM</strong> signal to the same node process to illustrate signal trapping, after which we output "terminating" and exit. Note that our second timeout of 1000 milliseconds is never reached.</p>
498
499 <pre><code>process.on('SIGTERM', function(){
500 console.log('terminating');
501 process.exit(1);
502 });
503
504 setTimeout(function(){
505 console.log('sending SIGTERM to process %d', process.pid);
506 process.kill(process.pid, 'SIGTERM');
507 }, 500);
508
509 setTimeout(function(){
510 console.log('never called');
511 }, 1000);
512 </code></pre>
513
514 <h3 id="errno">errno</h3>
515
fa384c9 @tj Regenerated book
tj authored Sep 7, 2010
516 <p>The <code>process</code> object is host of the error numbers, these reference what you would find in C-land, for example <code>process.EPERM</code> represents a permission based error, while <code>process.ENOENT</code> represents a missing file or directory. Typically these are used within bindings to bridge the gap between C++ and JavaScript, however useful for handling exceptions as well:</p>
2a420a7 @tj No longer gitignoring html
tj authored Aug 31, 2010
517
518 <pre><code>if (err.errno === process.ENOENT) {
519 // Display a 404 "Not Found" page
520 } else {
521 // Display a 500 "Internal Server Error" page
522 }
523 </code></pre>
524
525 </div>
526 <div class='mp'>
527 <h1>Events</h1>
2f6a03c @tj Added mobi and epub to `make all`
tj authored Sep 2, 2010
528 <p> The concept of an "event" is crucial to node, and used greatly throughout core and 3rd-party modules. Node's core module <em>events</em> supplies us with a single constructor, <em>EventEmitter</em>.</p>
2a420a7 @tj No longer gitignoring html
tj authored Aug 31, 2010
529
530 <h2 id="Emitting-Events">Emitting Events</h2>
531
532 <p>Typically an object inherits from <em>EventEmitter</em>, however our small example below illustrates the api. First we create an <code>emitter</code>, after which we can define any number of callbacks using the <code>emitter.on()</code> method which accepts the <em>name</em> of the event, and arbitrary objects passed as data. When <code>emitter.emit()</code> is called we are only required to pass the event <em>name</em>, followed by any number of arguments, in this case the <code>first</code> and <code>last</code> name strings.</p>
533
534 <pre><code>var EventEmitter = require('events').EventEmitter;
535
536 var emitter = new EventEmitter;
537
538 emitter.on('name', function(first, last){
539 console.log(first + ', ' + last);
540 });
541
542 emitter.emit('name', 'tj', 'holowaychuk');
543 emitter.emit('name', 'simon', 'holowaychuk');
544 </code></pre>
545
546 <h2 id="Inheriting-From-EventEmitter">Inheriting From EventEmitter</h2>
547
fa384c9 @tj Regenerated book
tj authored Sep 7, 2010
548 <p>A perhaps more practical use of <code>EventEmitter</code>, and commonly used throughout node is to inherit from it. This means we can leave <code>EventEmitter</code>'s prototype untouched, while utilizing its api for our own means of world domination!</p>
2a420a7 @tj No longer gitignoring html
tj authored Aug 31, 2010
549
550 <p>To do so we begin by defining the <code>Dog</code> constructor, which of course will bark from time to time, also known as an <em>event</em>. Our <code>Dog</code> constructor accepts a <code>name</code>, followed by <code>EventEmitter.call(this)</code>, which invokes the <code>EventEmitter</code> function in context to the given argument. Doing this is essentially the same as a "super" or "parent" call in languages that support classes. This is a crucial step, as it allows <code>EventEmitter</code> to set up the <code>_events</code> property which it utilizes internally to manage callbacks.</p>
551
552 <pre><code>var EventEmitter = require('events').EventEmitter;
553
554 function Dog(name) {
555 this.name = name;
556 EventEmitter.call(this);
557 }
558 </code></pre>
559
560 <p>Here we inherit from <code>EventEmitter</code>, so that we may use the methods provided such as <code>EventEmitter#on()</code> and <code>EventEmitter#emit()</code>. If the <code>__proto__</code> property is throwing you off, no worries! we will be touching on this later.</p>
561
562 <pre><code>Dog.prototype.__proto__ = EventEmitter.prototype;
563 </code></pre>
564
565 <p>Now that we have our <code>Dog</code> set up, we can create .... simon! When simon barks we can let <em>stdout</em> know by calling <code>console.log()</code> within the callback. The callback it-self is called in context to the object, aka <code>this</code>.</p>
566
567 <pre><code>var simon = new Dog('simon');
568
569 simon.on('bark', function(){
570 console.log(this.name + ' barked');
571 });
572 </code></pre>
573
574 <p>Bark twice a second:</p>
575
576 <pre><code>setInterval(function(){
577 simon.emit('bark');
578 }, 500);
579 </code></pre>
580
581 <h2 id="Removing-Event-Listeners">Removing Event Listeners</h2>
582
583 <p>As we have seen event listeners are simply functions which are called when we <code>emit()</code> an event. Although not seen often we can remove these listeners by calling the <code>removeListener(type, callback)</code> method. In the example below we emit the <em>message</em> "foo bar" every <code>300</code> milliseconds, which has the callback of <code>console.log()</code>. After 1000 milliseconds we call <code>removeListener()</code> with the same arguments that we passed to <code>on()</code> originally. To compliment this method is <code>removeAllListeners(type)</code> which removes all listeners associated to the given <em>type</em>.</p>
584
585 <pre><code>var EventEmitter = require('events').EventEmitter;
586
587 var emitter = new EventEmitter;
588
589 emitter.on('message', console.log);
590
591 setInterval(function(){
592 emitter.emit('message', 'foo bar');
593 }, 300);
594
595 setTimeout(function(){
596 emitter.removeListener('message', console.log);
597 }, 1000);
598 </code></pre>
599
600 </div>
601 <div class='mp'>
602 <h1>Buffers</h1>
2f6a03c @tj Added mobi and epub to `make all`
tj authored Sep 2, 2010
603 <p> To handle binary data, node provides us with the global <code>Buffer</code> object. Buffer instances represent memory allocated independently to that of V8's heap. There are several ways to construct a <code>Buffer</code> instance, and many ways you can manipulate it's data.</p>
2a420a7 @tj No longer gitignoring html
tj authored Aug 31, 2010
604
605 <p>The simplest way to construct a <code>Buffer</code> from a string is to simply pass a string as the first argument. As you can see by the log output, we now have a buffer object containing 5 bytes of data represented in hexadecimal.</p>
606
607 <pre><code>var hello = new Buffer('Hello');
608
609 console.log(hello);
610 // =&gt; &lt;Buffer 48 65 6c 6c 6f>
611
612 console.log(hello.toString());
613 // =&gt; "Hello"
614 </code></pre>
615
616 <p>By default the encoding is "utf8", however this can be specified by passing as string as the second argument. The ellipsis below for example will be printed to stdout as the '&amp;' character when in "ascii" encoding.</p>
617
618 <pre><code>var buf = new Buffer('…');
619 console.log(buf.toString());
620 // =&gt;
621
622 var buf = new Buffer('…', 'ascii');
623 console.log(buf.toString());
624 // =&gt; &amp;
625 </code></pre>
626
627 <p>An alternative method is to pass an array of integers representing the octet stream, however in this case functionality equivalent.</p>
628
629 <pre><code>var hello = new Buffer([0x48, 0x65, 0x6c, 0x6c, 0x6f]);
630 </code></pre>
631
632 <p>Buffers can also be created with an integer representing the number of bytes allocated, after which we may call the <code>write()</code> method, providing an optional offset and encoding. As shown below we provide the offset of 2 bytes to our second call to <code>write()</code>, buffering "Hel", and then we continue on to write another two bytes with an offset of 3, completing "Hello".</p>
633
634 <pre><code>var buf = new Buffer(5);
635 buf.write('He');
636 buf.write('l', 2);
637 buf.write('lo', 3);
638 console.log(buf.toString());
639 // =&gt; "Hello"
640 </code></pre>
641
2f6a03c @tj Added mobi and epub to `make all`
tj authored Sep 2, 2010
642 <p>The <code>.length</code> property of a buffer instance contains the byte length of the stream, opposed to JavaScript strings which will simply return the number of characters. For example the ellipsis character '…' consists of three bytes, however the buffer will respond with the byte length, and not the character length.</p>
2a420a7 @tj No longer gitignoring html
tj authored Aug 31, 2010
643
644 <pre><code>var ellipsis = new Buffer('…', 'utf8');
645
646 console.log('… string length: %d', '…'.length);
647 // =&gt; … string length: 1
648
649 console.log('… byte length: %d', ellipsis.length);
650 // =&gt; … byte length: 3
651
652 console.log(ellipsis);
653 // =&gt; &lt;Buffer e2 80 a6>
654 </code></pre>
655
2f6a03c @tj Added mobi and epub to `make all`
tj authored Sep 2, 2010
656 <p>When dealing with JavaScript strings, we may pass it to the <code>Buffer.byteLength()</code> method to determine it's byte length.</p>
2a420a7 @tj No longer gitignoring html
tj authored Aug 31, 2010
657
2f6a03c @tj Added mobi and epub to `make all`
tj authored Sep 2, 2010
658 <p>The api is written in such a way that it is String-like, so for example we can work with "slices" of a <code>Buffer</code> by passing offsets to the <code>slice()</code> method:</p>
2a420a7 @tj No longer gitignoring html
tj authored Aug 31, 2010
659
660 <pre><code>var chunk = buf.slice(4, 9);
661 console.log(chunk.toString());
662 // =&gt; "some"
663 </code></pre>
664
665 <p>Alternatively when expecting a string we can pass offsets to <code>Buffer#toString()</code>:</p>
666
667 <pre><code>var buf = new Buffer('just some data');
668 console.log(buf.toString('ascii', 4, 9));
669 // =&gt; "some"
670 </code></pre>
671
672 </div>
673 <div class='mp'>
674 <h1>Streams</h1>
675 <p> Streams are an important concept in node. The stream api is a unified way to handle stream-like data, for example data can be streamed to a file, streamed to a socket to respond to an HTTP request, or a stream can be read-only such as reading from <em>stdin</em>. However since we will be touching on stream specifics in later chapters, for now we will concentrate on the api.</p>
676
677 <h2 id="Readable-Streams">Readable Streams</h2>
678
679 <p> Readable streams such as an HTTP request inherit from <code>EventEmitter</code> in order to expose incoming data through events. The first of these events is the <em>data</em> event, which is an arbitrary chunk of data passed to the event handler as a <code>Buffer</code> instance.</p>
680
681 <pre><code>req.on('data', function(buf){
682 // Do something with the Buffer
683 });
684 </code></pre>
685
686 <p>As we know, we can call <code>toString()</code> a buffer to return a string representation of the binary data, however in the case of streams if desired we may call <code>setEncoding()</code> on the stream,
687 after which the <em>data</em> event will emit strings.</p>
688
689 <pre><code>req.setEncoding('utf8');
690 req.on('data', function(str){
691 // Do something with the String
692 });
693 </code></pre>
694
695 <p>Another import event is the <em>end</em> event, which represents the ending of <em>data</em> events. For example below we define an HTTP echo server, simply "pumping" the request body data through to the response. So if we <strong>POST</strong> "hello world", our response will be "hello world".</p>
696
697 <pre><code>var http = require('http');
698
699 http.createServer(function(req, res){
700 res.writeHead(200);
701 req.on('data', function(data){
702 res.write(data);
703 });
704 req.on('end', function(){
705 res.end();
706 });
707 }).listen(3000);
708 </code></pre>
709
710 <p>The <em>sys</em> module actually has a function designed specifically for this "pumping" action, aptly named <code>sys.pump()</code>, which accepts a read stream as the first argument, and write stream as the second.</p>
711
712 <pre><code>var http = require('http'),
713 sys = require('sys');
714
715 http.createServer(function(req, res){
716 res.writeHead(200);
717 sys.pump(req, res);
718 }).listen(3000);
719 </code></pre>
720
721 </div>
722 <div class='mp'>
723 <h1>File System</h1>
724 <p> ...</p>
725
726 </div>
727 <div class='mp'>
728 <h1>TCP</h1>
729 <p> ...</p>
730
731 <h2 id="TCP-Servers">TCP Servers</h2>
732
733 <p> ...</p>
734
735 <h2 id="TCP-Clients">TCP Clients</h2>
736
737 <p> ...</p>
738
739 </div>
740 <div class='mp'>
741 <h1>HTTP</h1>
742 <p> ...</p>
743
744 <h2 id="HTTP-Servers">HTTP Servers</h2>
745
746 <p> ...</p>
747
748 <h2 id="HTTP-Clients">HTTP Clients</h2>
749
750 <p> ...</p>
751
752 </div>
753 <div class='mp'>
754 <h1>Connect</h1>
755 <p>Connect is a ...</p>
756
757 </div>
758 <div class='mp'>
759 <h1>Express</h1>
760 <p>Express is a ...</p>
761
762 </div>
763 <div class='mp'>
764 <h1>Testing</h1>
765 <p> ...</p>
766
767 <h2 id="Expresso">Expresso</h2>
768
769 <p> ...</p>
770
771 <h2 id="Vows">Vows</h2>
772
773 <p> ...</p>
774
775 </div>
776 <div class='mp'>
777 <h1>Deployment</h1>
778 <p> ...</p>
779
780 </div>
781 </body>
782 </html>
Something went wrong with that request. Please try again.