Skip to content
This repository
Browse code

re-generated

  • Loading branch information...
commit 6a8a2e78284f1ccdd18b468959e10bcf1b5807ef 1 parent f7356cb
TJ Holowaychuk authored
BIN  book.epub
Binary file not shown
207 book.html
@@ -99,213 +99,6 @@ <h2 id="Building-From-Source">Building From Source</h2>
99 99
100 100 </div>
101 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   -
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>
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>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>
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   -
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>
267   -
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>
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   -
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>
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   -
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>
291   -
292   -<pre><code>require.registerExtension('.ejs', require('./compiler/extended').compile);
293   -</code></pre>
294   -
295   -<p>Now when we require our example, the ".ejs" extension is detected, and will pass the contents through our compiler.</p>
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 102 <h1>Globals</h1>
310 103 <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>
311 104
BIN  book.mobi
Binary file not shown
BIN  book.pdf
Binary file not shown
207 chapters/modules.html
... ... @@ -1,207 +0,0 @@
1   -<div class='mp'>
2   -<h1>CommonJS Module System</h1>
3   -<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>
4   -
5   -<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>
6   -
7   -<h2 id="Creating-Modules">Creating Modules</h2>
8   -
9   -<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>
10   -
11   -<pre><code>var utils = {};
12   - utils.merge = function(obj, other) {};
13   -</code></pre>
14   -
15   -<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>
16   -
17   -<pre><code>var module = { exports: {}};
18   - (function(module, exports){
19   - function merge(){};
20   - exports.merge = merge;
21   - })(module, module.exports);
22   -</code></pre>
23   -
24   -<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>
25   -
26   -<pre><code> function merge(obj, other) {
27   - var keys = Object.keys(other);
28   - for (var i = 0, len = keys.length; i &lt; len; ++i) {
29   - var key = keys[i];
30   - obj[key] = other[key];
31   - }
32   - return obj;
33   - };
34   -
35   - exports.merge = merge;
36   -</code></pre>
37   -
38   -<p>The typical pattern for public properties is to simply define them
39   -on the <code>exports</code> object like so:</p>
40   -
41   -<pre><code>exports.merge = function(obj, other) {
42   - var keys = Object.keys(other);
43   - for (var i = 0, len = keys.length; i &lt; len; ++i) {
44   - var key = keys[i];
45   - obj[key] = other[key];
46   - }
47   - return obj;
48   -};
49   -</code></pre>
50   -
51   -<p>Next we will look at utilizing out new module in other libraries.</p>
52   -
53   -<h2 id="Requiring-Modules">Requiring Modules</h2>
54   -
55   -<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>
56   -
57   -<pre><code>var utils = require('./utils');
58   -
59   -var a = { one: 1 };
60   -var b = { two: 2 };
61   -utils.merge(a, b);
62   -console.dir(a);
63   -</code></pre>
64   -
65   -<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>
66   -
67   -<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>
68   -
69   -<pre><code>module.exports = {
70   - add: require('./add'),
71   - sub: require('./sub')
72   -};
73   -</code></pre>
74   -
75   -<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>
76   -
77   -<pre><code>module.exports = function add(a, b){
78   - return a + b;
79   -};
80   -</code></pre>
81   -
82   -<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>
83   -
84   -<pre><code>exports.Animal = function Animal(){};
85   -</code></pre>
86   -
87   -<p>which can then be utilized as shown:</p>
88   -
89   -<pre><code>var Animal = require('./animal').Animal;
90   -</code></pre>
91   -
92   -<p>if we change our module slightly, we can remove <code>.Animal</code>:</p>
93   -
94   -<pre><code>module.exports = function Animal(){};
95   -</code></pre>
96   -
97   -<p>which can now be used without the property:</p>
98   -
99   -<pre><code>var Animal = require('./animal');
100   -</code></pre>
101   -
102   -<h2 id="Require-Paths">Require Paths</h2>
103   -
104   -<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>
105   -
106   -<ul>
107   -<li><code>&lt;node binary></code>/../../lib/node</li>
108   -<li><strong>$HOME</strong>/.node_libraries</li>
109   -<li><strong>$NODE_PATH</strong></li>
110   -</ul>
111   -
112   -
113   -<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>
114   -
115   -<h3 id="Runtime-Manipulation">Runtime Manipulation</h3>
116   -
117   -<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>
118   -
119   -<pre><code>require.paths.unshift(__dirname + '/math');
120   -
121   -var add = require('add'),
122   - sub = require('sub');
123   -
124   -console.log(add(1,2));
125   -console.log(sub(1,2));
126   -</code></pre>
127   -
128   -<h2 id="Pseudo-Globals">Pseudo Globals</h2>
129   -
130   -<p>As mentioned above, modules have several pseudo globals available to them, these are as follows:</p>
131   -
132   -<ul>
133   -<li><code>require</code> the require function itself</li>
134   -<li><code>module</code> the current <code>Module</code> instance</li>
135   -<li><code>exports</code> the current module's exported properties</li>
136   -<li><code>__filename</code> absolute path to the current module's file</li>
137   -<li><code>__dirname</code> absolute path to the current module's directory</li>
138   -</ul>
139   -
140   -
141   -<h3 id="require-">require()</h3>
142   -
143   -<p>Although not obvious at first glance, the <code>require()</code> function is actually
144   -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>
145   -
146   -<h3 id="module">module</h3>
147   -
148   -<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>
149   -
150   -<pre><code>// css.js
151   -module.exports = 'body { background: blue; }';
152   -</code></pre>
153   -
154   -<p>To obtain this string we would simply <code>require('./css')</code>. The <code>module</code> object also contains these useful properties:</p>
155   -
156   -<ul>
157   -<li><code>id</code> the module's id, consisting of a path. Ex: <code>./app</code></li>
158   -<li><code>parent</code> the parent <code>Module</code> (which required this one) or <code>undefined</code></li>
159   -<li><code>filename</code> absolute path to the module</li>
160   -<li><code>moduleCache</code> an object containing references to all cached modules</li>
161   -</ul>
162   -
163   -
164   -<h2 id="Registering-Module-Compilers">Registering Module Compilers</h2>
165   -
166   -<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>
167   -
168   -<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>
169   -
170   -<pre><code>::min(a, b) a &lt; b ? a : b
171   -::max(a, b) a &gt; b ? a : b
172   -</code></pre>
173   -
174   -<p>which will be compiled to:</p>
175   -
176   -<pre><code>exports.min = function min(a, b) { return a &lt; b ? a : b }
177   -exports.max = function max(a, b) { return a &gt; b ? a : b }
178   -</code></pre>
179   -
180   -<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>
181   -
182   -<pre><code>exports.compile = function(str){
183   - return str
184   - .replace(/(\w+)\(/g, '$1 = function $1(')
185   - .replace(/\)(.+?)\n/g, '){ return $1 }\n')
186   - .replace(/::/g, 'exports.');
187   -};
188   -</code></pre>
189   -
190   -<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>
191   -
192   -<pre><code>require.registerExtension('.ejs', require('./compiler/extended').compile);
193   -</code></pre>
194   -
195   -<p>Now when we require our example, the ".ejs" extension is detected, and will pass the contents through our compiler.</p>
196   -
197   -<pre><code>var example = require('./compiler/example');
198   -console.dir(example)
199   -console.log(example.min(2, 3));
200   -console.log(example.max(10, 8));
201   -
202   -// =&gt; { min: [Function], max: [Function] }
203   -// =&gt; 2
204   -// =&gt; 10
205   -</code></pre>
206   -
207   -</div>

0 comments on commit 6a8a2e7

Please sign in to comment.
Something went wrong with that request. Please try again.