Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 833 lines (577 sloc) 36.309 kB
2a420a7 @tj No longer gitignoring html
tj authored
1 <html>
2 <head>
3 <title>Mastering Node</title>
4 <style>
5 body {
69df60f @tj Added crappy default theme
tj authored
6 font: 14px/1.4 "Lucida Grande", "Helvetica Neue", Arial, sans-serif;
2a420a7 @tj No longer gitignoring html
tj authored
7 padding: 50px 180px;
8 }
69df60f @tj Added crappy default theme
tj authored
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
21 </style>
22 </head>
23 <body><div class='mp'>
2a420a7 @tj No longer gitignoring html
tj authored
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
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
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
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
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
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
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
57ea666 @tj Regenerated book
tj authored
155 <p>To get started with requiring modules, first 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>
2a420a7 @tj No longer gitignoring html
tj authored
156
157 <pre><code>var utils = require('./utils');
158
159 var a = { one: 1 };
160 var b = { two: 2 };
161 utils.merge(a, b);
162 console.dir(a);
163 </code></pre>
164
165 <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>
166
167 <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>
168
169 <pre><code>module.exports = {
170 add: require('./add'),
171 sub: require('./sub')
172 };
173 </code></pre>
174
175 <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>
176
177 <pre><code>module.exports = function add(a, b){
178 return a + b;
179 };
180 </code></pre>
181
182 <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>
183
184 <pre><code>exports.Animal = function Animal(){};
185 </code></pre>
186
187 <p>which can then be utilized as shown:</p>
188
189 <pre><code>var Animal = require('./animal').Animal;
190 </code></pre>
191
192 <p>if we change our module slightly, we can remove <code>.Animal</code>:</p>
193
194 <pre><code>module.exports = function Animal(){};
195 </code></pre>
196
197 <p>which can now be used without the property:</p>
198
199 <pre><code>var Animal = require('./animal');
200 </code></pre>
201
202 <h2 id="Require-Paths">Require Paths</h2>
203
204 <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>
205
206 <ul>
207 <li><code>&lt;node binary></code>/../../lib/node</li>
208 <li><strong>$HOME</strong>/.node_libraries</li>
209 <li><strong>$NODE_PATH</strong></li>
210 </ul>
211
212
213 <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>
214
215 <h3 id="Runtime-Manipulation">Runtime Manipulation</h3>
216
217 <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>
218
219 <pre><code>require.paths.unshift(__dirname + '/math');
220
221 var add = require('add'),
222 sub = require('sub');
223
224 console.log(add(1,2));
225 console.log(sub(1,2));
226 </code></pre>
227
228 <h2 id="Pseudo-Globals">Pseudo Globals</h2>
229
230 <p>As mentioned above, modules have several pseudo globals available to them, these are as follows:</p>
231
232 <ul>
233 <li><code>require</code> the require function itself</li>
234 <li><code>module</code> the current <code>Module</code> instance</li>
235 <li><code>exports</code> the current module's exported properties</li>
236 <li><code>__filename</code> absolute path to the current module's file</li>
237 <li><code>__dirname</code> absolute path to the current module's directory</li>
238 </ul>
239
240
241 <h3 id="require-">require()</h3>
242
243 <p>Although not obvious at first glance, the <code>require()</code> function is actually
244 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>
245
246 <h3 id="module">module</h3>
247
248 <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>
249
250 <pre><code>// css.js
251 module.exports = 'body { background: blue; }';
252 </code></pre>
253
254 <p>To obtain this string we would simply <code>require('./css')</code>. The <code>module</code> object also contains these useful properties:</p>
255
256 <ul>
257 <li><code>id</code> the module's id, consisting of a path. Ex: <code>./app</code></li>
258 <li><code>parent</code> the parent <code>Module</code> (which required this one) or <code>undefined</code></li>
259 <li><code>filename</code> absolute path to the module</li>
260 <li><code>moduleCache</code> an object containing references to all cached modules</li>
261 </ul>
262
263
264 <h2 id="Registering-Module-Compilers">Registering Module Compilers</h2>
265
fa384c9 @tj Regenerated book
tj authored
266 <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
267
fa384c9 @tj Regenerated book
tj authored
268 <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
269
270 <pre><code>::min(a, b) a &lt; b ? a : b
271 ::max(a, b) a &gt; b ? a : b
272 </code></pre>
273
274 <p>which will be compiled to:</p>
275
276 <pre><code>exports.min = function min(a, b) { return a &lt; b ? a : b }
277 exports.max = function max(a, b) { return a &gt; b ? a : b }
278 </code></pre>
279
fa384c9 @tj Regenerated book
tj authored
280 <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
281
282 <pre><code>exports.compile = function(str){
283 return str
284 .replace(/(\w+)\(/g, '$1 = function $1(')
285 .replace(/\)(.+?)\n/g, '){ return $1 }\n')
286 .replace(/::/g, 'exports.');
287 };
288 </code></pre>
289
4273080 Fix typo, clean up awkward sentence
Grant Heaslip authored
290 <p>Next we have to "register" the extension to assign our compiler. As previously mentioned, our compiler lives at <em>./compiler/extended.js</em>; so we are requiring it, 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>
2a420a7 @tj No longer gitignoring html
tj authored
291
292 <pre><code>require.registerExtension('.ejs', require('./compiler/extended').compile);
293 </code></pre>
294
30a1d1c Remove redundant (and awkward) "and everything works as expected"
Grant Heaslip authored
295 <p>Now when we require our example, the ".ejs" extension is detected, and will pass the contents through our compiler.</p>
2a420a7 @tj No longer gitignoring html
tj authored
296
297 <pre><code>var example = require('./compiler/example');
298 console.dir(example)
299 console.log(example.min(2, 3));
300 console.log(example.max(10, 8));
301
302 // =&gt; { min: [Function], max: [Function] }
303 // =&gt; 2
304 // =&gt; 10
305 </code></pre>
306
307 </div>
308 <div class='mp'>
309 <h1>Globals</h1>
ef20620 Clean up flow of Globals chapter intro paragraph
Grant Heaslip authored
310 <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, such as the <code>console</code> object, are provided to those used to writing JavaScript for web browsers.</p>
2a420a7 @tj No longer gitignoring html
tj authored
311
312 <h2 id="console">console</h2>
313
fdf60a0 Clean up some console object descriptions
Grant Heaslip authored
314 <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
315
316 <h3 id="console-log-">console.log()</h3>
317
fdf60a0 Clean up some console object descriptions
Grant Heaslip authored
318 <p>The most frequently used console method is <code>console.log()</code>, which simply writes to <em>stdout</em> and appends a line feed (<code>\n</code>). Currently aliased as <code>console.info()</code>.</p>
2a420a7 @tj No longer gitignoring html
tj authored
319
320 <pre><code>console.log('wahoo');
321 // =&gt; wahoo
322
323 console.log({ foo: 'bar' });
324 // =&gt; [object Object]
325 </code></pre>
326
327 <h3 id="console-error-">console.error()</h3>
328
329 <p>Identical to <code>console.log()</code>, however writes to <em>stderr</em>. Aliased as <code>console.warn()</code> as well.</p>
330
331 <pre><code>console.error('database connection failed');
332 </code></pre>
333
334 <h3 id="console-dir-">console.dir()</h3>
335
336 <p>Utilizes the <em>sys</em> module's <code>inspect()</code> method to pretty-print the object to
337 <em>stdout</em>.</p>
338
339 <pre><code>console.dir({ foo: 'bar' });
340 // =&gt; { foo: 'bar' }
341 </code></pre>
342
343 <h3 id="console-assert-">console.assert()</h3>
344
345 <p>Asserts that the given expression is truthy, or throws an exception.</p>
346
347 <pre><code>console.assert(connected, 'Database connection failed');
348 </code></pre>
349
350 <h2 id="process">process</h2>
351
65f2cdd Clean up process object descriptions
Grant Heaslip authored
352 <p>The <code>process</code> object is plastered with goodies. First we will take a look
353 at some properties that provide information about the node process itself:</p>
2a420a7 @tj No longer gitignoring html
tj authored
354
355 <h3 id="process-version">process.version</h3>
356
65f2cdd Clean up process object descriptions
Grant Heaslip authored
357 <p>The node version string, for example "v0.1.103".</p>
2a420a7 @tj No longer gitignoring html
tj authored
358
359 <h3 id="process-installPrefix">process.installPrefix</h3>
360
65f2cdd Clean up process object descriptions
Grant Heaslip authored
361 <p>The installation prefix. In my case "<em>/usr/local</em>", as node's binary was installed to "<em>/usr/local/bin/node</em>".</p>
2a420a7 @tj No longer gitignoring html
tj authored
362
363 <h3 id="process-execPath">process.execPath</h3>
364
65f2cdd Clean up process object descriptions
Grant Heaslip authored
365 <p>The path to the executable itself "<em>/usr/local/bin/node</em>".</p>
2a420a7 @tj No longer gitignoring html
tj authored
366
367 <h3 id="process-platform">process.platform</h3>
368
65f2cdd Clean up process object descriptions
Grant Heaslip authored
369 <p>The platform you are running on. For example, "darwin".</p>
2a420a7 @tj No longer gitignoring html
tj authored
370
371 <h3 id="process-pid">process.pid</h3>
372
373 <p>The process id.</p>
374
375 <h3 id="process-cwd-">process.cwd()</h3>
376
65f2cdd Clean up process object descriptions
Grant Heaslip authored
377 <p>Returns the current working directory. For example:</p>
2a420a7 @tj No longer gitignoring html
tj authored
378
379 <pre><code>cd ~ &amp;&amp; node
380 node&gt; process.cwd()
381 "/Users/tj"
382 </code></pre>
383
384 <h3 id="process-chdir-">process.chdir()</h3>
385
386 <p>Changes the current working directory to the path passed.</p>
387
388 <pre><code>process.chdir('/foo');
389 </code></pre>
390
391 <h3 id="process-getuid-">process.getuid()</h3>
392
393 <p>Returns the numerical user id of the running process.</p>
394
395 <h3 id="process-setuid-">process.setuid()</h3>
396
397 <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>
398
399 <h3 id="process-getgid-">process.getgid()</h3>
400
401 <p>Returns the numerical group id of the running process.</p>
402
403 <h3 id="process-setgid-">process.setgid()</h3>
404
65f2cdd Clean up process object descriptions
Grant Heaslip authored
405 <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>
2a420a7 @tj No longer gitignoring html
tj authored
406
407 <h3 id="process-env">process.env</h3>
408
65f2cdd Clean up process object descriptions
Grant Heaslip authored
409 <p>An object containing the user's environment variables. For example:</p>
2a420a7 @tj No longer gitignoring html
tj authored
410
411 <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'
412 , PWD: '/Users/tj/ebooks/masteringnode'
413 , EDITOR: 'mate'
414 , LANG: 'en_CA.UTF-8'
415 , SHLVL: '1'
416 , HOME: '/Users/tj'
417 , LOGNAME: 'tj'
418 , DISPLAY: '/tmp/launch-YCkT03/org.x:0'
419 , _: '/usr/local/bin/node'
420 , OLDPWD: '/Users/tj'
421 }
422 </code></pre>
423
424 <h3 id="process-argv">process.argv</h3>
425
426 <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>
427
65f2cdd Clean up process object descriptions
Grant Heaslip authored
428 <p>For example, our source file <em>./src/process/misc.js</em> can be executed by running:</p>
2a420a7 @tj No longer gitignoring html
tj authored
429
430 <pre><code>$ node src/process/misc.js foo bar baz
431 </code></pre>
432
433 <p>in which we call <code>console.dir(process.argv)</code>, outputting the following:</p>
434
435 <pre><code>[ 'node'
436 , '/Users/tj/EBooks/masteringnode/src/process/misc.js'
437 , 'foo'
438 , 'bar'
439 , 'baz'
440 ]
441 </code></pre>
442
443 <h3 id="process-exit-">process.exit()</h3>
444
65f2cdd Clean up process object descriptions
Grant Heaslip authored
445 <p>The <code>process.exit()</code> method is synonymous with the C function <code>exit()</code>, in which an exit code > 0 is passed to indicate failure, or 0 is passed 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>
2a420a7 @tj No longer gitignoring html
tj authored
446
447 <h3 id="process-on-">process.on()</h3>
448
65f2cdd Clean up process object descriptions
Grant Heaslip authored
449 <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>
2a420a7 @tj No longer gitignoring html
tj authored
450
451 <pre><code>process.on('uncaughtException', function(err){
452 console.log('got an error: %s', err.message);
453 process.exit(1);
454 });
455
456 setTimeout(function(){
457 throw new Error('fail');
458 }, 100);
459 </code></pre>
460
461 <h3 id="process-kill-">process.kill()</h3>
462
65f2cdd Clean up process object descriptions
Grant Heaslip authored
463 <p><code>process.kill()</code> method sends the signal passed to the given <em>pid</em>, defaulting to <strong>SIGINT</strong>. In the 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 the second timeout of 1000 milliseconds is never reached.</p>
2a420a7 @tj No longer gitignoring html
tj authored
464
465 <pre><code>process.on('SIGTERM', function(){
466 console.log('terminating');
467 process.exit(1);
468 });
469
470 setTimeout(function(){
471 console.log('sending SIGTERM to process %d', process.pid);
472 process.kill(process.pid, 'SIGTERM');
473 }, 500);
474
475 setTimeout(function(){
476 console.log('never called');
477 }, 1000);
478 </code></pre>
479
480 <h3 id="errno">errno</h3>
481
65f2cdd Clean up process object descriptions
Grant Heaslip authored
482 <p>The <code>process</code> object is host of the error numbers, which 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, but they're useful for handling exceptions as well:</p>
2a420a7 @tj No longer gitignoring html
tj authored
483
484 <pre><code>if (err.errno === process.ENOENT) {
485 // Display a 404 "Not Found" page
486 } else {
487 // Display a 500 "Internal Server Error" page
488 }
489 </code></pre>
490
491 </div>
492 <div class='mp'>
493 <h1>Events</h1>
9b1e95a Clean up events chapter
Grant Heaslip authored
494 <p> The concept of an "event" is crucial to node, and is used heavily 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
495
496 <h2 id="Emitting-Events">Emitting Events</h2>
497
9b1e95a Clean up events chapter
Grant Heaslip authored
498 <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>
2a420a7 @tj No longer gitignoring html
tj authored
499
500 <pre><code>var EventEmitter = require('events').EventEmitter;
501
502 var emitter = new EventEmitter;
503
504 emitter.on('name', function(first, last){
505 console.log(first + ', ' + last);
506 });
507
508 emitter.emit('name', 'tj', 'holowaychuk');
509 emitter.emit('name', 'simon', 'holowaychuk');
510 </code></pre>
511
512 <h2 id="Inheriting-From-EventEmitter">Inheriting From EventEmitter</h2>
513
9b1e95a Clean up events chapter
Grant Heaslip authored
514 <p>A more practical and common use of <code>EventEmitter</code> 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
515
9b1e95a Clean up events chapter
Grant Heaslip authored
516 <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>).</p>
2a420a7 @tj No longer gitignoring html
tj authored
517
518 <pre><code>var EventEmitter = require('events').EventEmitter;
519
520 function Dog(name) {
521 this.name = name;
522 }
523 </code></pre>
524
9b1e95a Clean up events chapter
Grant Heaslip authored
525 <p>Here we inherit from <code>EventEmitter</code> so we can use the methods it provides, such as <code>EventEmitter#on()</code> and <code>EventEmitter#emit()</code>. If the <code>__proto__</code> property is throwing you off, don't worry, we'll be coming back to this later.</p>
2a420a7 @tj No longer gitignoring html
tj authored
526
527 <pre><code>Dog.prototype.__proto__ = EventEmitter.prototype;
528 </code></pre>
529
9b1e95a Clean up events chapter
Grant Heaslip authored
530 <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 itself is called in the context of the object (aka <code>this</code>).</p>
2a420a7 @tj No longer gitignoring html
tj authored
531
532 <pre><code>var simon = new Dog('simon');
533
534 simon.on('bark', function(){
535 console.log(this.name + ' barked');
536 });
537 </code></pre>
538
9b1e95a Clean up events chapter
Grant Heaslip authored
539 <p>Bark twice per second:</p>
2a420a7 @tj No longer gitignoring html
tj authored
540
541 <pre><code>setInterval(function(){
542 simon.emit('bark');
543 }, 500);
544 </code></pre>
545
546 <h2 id="Removing-Event-Listeners">Removing Event Listeners</h2>
547
9b1e95a Clean up events chapter
Grant Heaslip authored
548 <p>As we have seen, event listeners are simply functions which are called when we <code>emit()</code> an event. We can remove these listeners by calling the <code>removeListener(type, callback)</code> method, although this isn't seen often. In the example below we emit the <em>message</em> "foo bar" every <code>300</code> milliseconds, which has a 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. We could also have used <code>removeAllListeners(type)</code>, which removes all listeners registered to the given <em>type</em>.</p>
2a420a7 @tj No longer gitignoring html
tj authored
549
550 <pre><code>var EventEmitter = require('events').EventEmitter;
551
552 var emitter = new EventEmitter;
553
554 emitter.on('message', console.log);
555
556 setInterval(function(){
557 emitter.emit('message', 'foo bar');
558 }, 300);
559
560 setTimeout(function(){
561 emitter.removeListener('message', console.log);
562 }, 1000);
563 </code></pre>
564
565 </div>
566 <div class='mp'>
567 <h1>Buffers</h1>
7faeaaa Clean up buffers chapter
Grant Heaslip authored
568 <p> To handle binary data, node provides us with the global <code>Buffer</code> object. <code>Buffer</code> instances represent memory allocated independently of V8's heap. There are several ways to construct a <code>Buffer</code> instance, and many ways you can manipulate its data.</p>
2a420a7 @tj No longer gitignoring html
tj authored
569
7faeaaa Clean up buffers chapter
Grant Heaslip authored
570 <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 in the log output, we now have a buffer object containing 5 bytes of data represented in hexadecimal.</p>
2a420a7 @tj No longer gitignoring html
tj authored
571
572 <pre><code>var hello = new Buffer('Hello');
573
574 console.log(hello);
575 // =&gt; &lt;Buffer 48 65 6c 6c 6f>
576
577 console.log(hello.toString());
578 // =&gt; "Hello"
579 </code></pre>
580
7faeaaa Clean up buffers chapter
Grant Heaslip authored
581 <p>By default, the encoding is "utf8", but this can be overridden by passing a string as the second argument. For example, the ellipsis below will be printed to stdout as the "&amp;" character when in "ascii" encoding.</p>
2a420a7 @tj No longer gitignoring html
tj authored
582
583 <pre><code>var buf = new Buffer('…');
584 console.log(buf.toString());
585 // =&gt;
586
587 var buf = new Buffer('…', 'ascii');
588 console.log(buf.toString());
589 // =&gt; &amp;
590 </code></pre>
591
7faeaaa Clean up buffers chapter
Grant Heaslip authored
592 <p>An alternative (but in this case functionality equivalent) method is to pass an array of integers representing the octet stream.</p>
2a420a7 @tj No longer gitignoring html
tj authored
593
594 <pre><code>var hello = new Buffer([0x48, 0x65, 0x6c, 0x6c, 0x6f]);
595 </code></pre>
596
7faeaaa Clean up buffers chapter
Grant Heaslip authored
597 <p>Buffers can also be created with an integer representing the number of bytes allocated, after which we can call the <code>write()</code> method, providing an optional offset and encoding. Below, we provide an offset of 2 bytes to our second call to <code>write()</code> (buffering "Hel") and then write another two bytes with an offset of 3 (completing "Hello").</p>
2a420a7 @tj No longer gitignoring html
tj authored
598
599 <pre><code>var buf = new Buffer(5);
600 buf.write('He');
601 buf.write('l', 2);
602 buf.write('lo', 3);
603 console.log(buf.toString());
604 // =&gt; "Hello"
605 </code></pre>
606
7faeaaa Clean up buffers chapter
Grant Heaslip authored
607 <p>The <code>.length</code> property of a buffer instance contains the byte length of the stream, as opposed to native strings, which simply return the number of characters. For example, the ellipsis character '…' consists of three bytes, so the buffer will respond with the byte length (3), and not the character length (1).</p>
2a420a7 @tj No longer gitignoring html
tj authored
608
609 <pre><code>var ellipsis = new Buffer('…', 'utf8');
610
611 console.log('… string length: %d', '…'.length);
612 // =&gt; … string length: 1
613
614 console.log('… byte length: %d', ellipsis.length);
615 // =&gt; … byte length: 3
616
617 console.log(ellipsis);
618 // =&gt; &lt;Buffer e2 80 a6>
619 </code></pre>
620
7faeaaa Clean up buffers chapter
Grant Heaslip authored
621 <p>To determine the byte length of a native string, pass it to the <code>Buffer.byteLength()</code> method.</p>
2a420a7 @tj No longer gitignoring html
tj authored
622
7faeaaa Clean up buffers chapter
Grant Heaslip authored
623 <p>The API is written in such a way that it is String-like. 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
624
625 <pre><code>var chunk = buf.slice(4, 9);
626 console.log(chunk.toString());
627 // =&gt; "some"
628 </code></pre>
629
7faeaaa Clean up buffers chapter
Grant Heaslip authored
630 <p>Alternatively, when expecting a string, we can pass offsets to <code>Buffer#toString()</code>:</p>
2a420a7 @tj No longer gitignoring html
tj authored
631
632 <pre><code>var buf = new Buffer('just some data');
633 console.log(buf.toString('ascii', 4, 9));
634 // =&gt; "some"
635 </code></pre>
636
637 </div>
638 <div class='mp'>
639 <h1>Streams</h1>
640 <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>
641
642 <h2 id="Readable-Streams">Readable Streams</h2>
643
644 <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>
645
646 <pre><code>req.on('data', function(buf){
647 // Do something with the Buffer
648 });
649 </code></pre>
650
651 <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,
652 after which the <em>data</em> event will emit strings.</p>
653
654 <pre><code>req.setEncoding('utf8');
655 req.on('data', function(str){
656 // Do something with the String
657 });
658 </code></pre>
659
660 <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>
661
662 <pre><code>var http = require('http');
663
664 http.createServer(function(req, res){
665 res.writeHead(200);
666 req.on('data', function(data){
667 res.write(data);
668 });
669 req.on('end', function(){
670 res.end();
671 });
672 }).listen(3000);
673 </code></pre>
674
675 <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>
676
677 <pre><code>var http = require('http'),
678 sys = require('sys');
679
680 http.createServer(function(req, res){
681 res.writeHead(200);
682 sys.pump(req, res);
683 }).listen(3000);
684 </code></pre>
685
686 </div>
687 <div class='mp'>
688 <h1>File System</h1>
960af03 @tj Regenerated book
tj authored
689 <p> To work with the filesystem, node provides the 'fs' module. The commands follow the POSIX operations, with most methods supporting an asynchronous and synchronous method call. We will look at how to use both and then establish which is the better option.</p>
690
691 <h2 id="Working-with-the-filesystem">Working with the filesystem</h2>
692
693 <p> Lets start with a basic example of working with the filesystem, this example creates a directory, it then creates a file in it. Once the file has been created the contents of the file are written to console:</p>
694
695 <pre><code>var fs = require('fs');
696
697 fs.mkdir('./helloDir',0777, function (err) {
698 if (err) throw err;
699
700 fs.writeFile('./helloDir/message.txt', 'Hello Node', function (err) {
701 if (err) throw err;
702 console.log('file created with contents:');
703
704 fs.readFile('./helloDir/message.txt','UTF-8' ,function (err, data) {
705 if (err) throw err;
706 console.log(data);
707 });
708 });
709 });
710 </code></pre>
711
712 <p> As evident in the example above, each callback is placed in the previous callback - this is what is referred to as chainable callbacks. When using asynchronous methods this pattern should be used, as there is no guarantee that the operations will be completed in the order that they are created. This could lead to unpredictable behavior.</p>
713
714 <p> The example can be rewritten to use a synchronous approach:</p>
715
716 <pre><code>fs.mkdirSync('./helloDirSync',0777);
717 fs.writeFileSync('./helloDirSync/message.txt', 'Hello Node');
718 var data = fs.readFileSync('./helloDirSync/message.txt','UTF-8');
719 console.log('file created with contents:');
720 console.log(data);
721 </code></pre>
722
723 <p> It is better to use the asynchronous approach on servers with a high load, as the synchronous methods will cause the whole process to halt and wait for the operation to complete. This will block any incoming connections and other events.</p>
724
725 <h2 id="File-information">File information</h2>
726
727 <p> The fs.Stats object contains information about a particular file or directory. This can be used to determine what type of object we
728 are working with. In this example we are getting all the file objects in a directory and displaying whether they are a file or a
729 directory object.</p>
730
731 <pre><code>var fs = require('fs');
732
733 fs.readdir('/etc/', function (err, files) {
734 if (err) throw err;
735
736 files.forEach( function (file) {
737 fs.stat('/etc/' + file, function (err, stats) {
738 if (err) throw err;
739
740 if (stats.isFile()) {
741 console.log("%s is file", file);
742 }
743 else if (stats.isDirectory ()) {
744 console.log("%s is a directory", file);
745 }
746 console.log('stats: %s',JSON.stringify(stats));
747 });
748 });
749 });
750 </code></pre>
751
752 <h2 id="Watching-files">Watching files</h2>
753
754 <p> The fs.watchfile monitors a file and will fire the event whenever the file is changed.</p>
755
756 <pre><code>var fs = require('fs');
757
758 fs.watchFile('./testFile.txt', function (curr, prev) {
759 console.log('the current mtime is: ' + curr.mtime);
760 console.log('the previous mtime was: ' + prev.mtime);
761 });
762
763 fs.writeFile('./testFile.txt', "changed", function (err) {
764 if (err) throw err;
765
766 console.log("file write complete");
767 });
768 </code></pre>
769
770 <p> A file can also be unwatched using the fs.unwatchFile method call. This is used once monitoring of a file is no longer required.</p>
771
772 <h2 id="Nodejs-Docs-for-further-reading">Nodejs Docs for further reading</h2>
773
774 <p> The node api <a href="http://nodejs.org/api.html#file-system-106">docs</a> are very detailed and list all the possible filesystem commands
775 available when working with Nodejs.</p>
2a420a7 @tj No longer gitignoring html
tj authored
776
777 </div>
778 <div class='mp'>
779 <h1>TCP</h1>
780 <p> ...</p>
781
782 <h2 id="TCP-Servers">TCP Servers</h2>
783
784 <p> ...</p>
785
786 <h2 id="TCP-Clients">TCP Clients</h2>
787
788 <p> ...</p>
789
790 </div>
791 <div class='mp'>
792 <h1>HTTP</h1>
793 <p> ...</p>
794
795 <h2 id="HTTP-Servers">HTTP Servers</h2>
796
797 <p> ...</p>
798
799 <h2 id="HTTP-Clients">HTTP Clients</h2>
800
801 <p> ...</p>
802
803 </div>
804 <div class='mp'>
805 <h1>Connect</h1>
806 <p>Connect is a ...</p>
807
808 </div>
809 <div class='mp'>
810 <h1>Express</h1>
811 <p>Express is a ...</p>
812
813 </div>
814 <div class='mp'>
815 <h1>Testing</h1>
816 <p> ...</p>
817
818 <h2 id="Expresso">Expresso</h2>
819
820 <p> ...</p>
821
822 <h2 id="Vows">Vows</h2>
823
824 <p> ...</p>
825
826 </div>
827 <div class='mp'>
828 <h1>Deployment</h1>
829 <p> ...</p>
830
831 </div>
832 </body>
833 </html>
Something went wrong with that request. Please try again.