1 | <!DOCTYPE html>
|
2 |
|
3 | <html>
|
4 | <head>
|
5 | <title>denodify-helper.js</title>
|
6 | <meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
7 | <meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
|
8 | <link rel="stylesheet" media="all" href="docco.css" />
|
9 | </head>
|
10 | <body>
|
11 | <div id="container">
|
12 | <div id="background"></div>
|
13 |
|
14 | <ul class="sections">
|
15 |
|
16 | <li id="title">
|
17 | <div class="annotation">
|
18 | <h1>denodify-helper.js</h1>
|
19 | </div>
|
20 | </li>
|
21 |
|
22 |
|
23 |
|
24 | <li id="section-1">
|
25 | <div class="annotation">
|
26 |
|
27 | <div class="pilwrap ">
|
28 | <a class="pilcrow" href="#section-1">¶</a>
|
29 | </div>
|
30 |
|
31 | </div>
|
32 |
|
33 | <div class="content"><div class='highlight'><pre><span class="hljs-keyword">var</span> Path = <span class="hljs-built_in">require</span>(<span class="hljs-string">'path'</span>);
|
34 | <span class="hljs-keyword">var</span> required = <span class="hljs-built_in">require</span>(<span class="hljs-string">'required'</span>);
|
35 | <span class="hljs-keyword">var</span> fs = <span class="hljs-built_in">require</span>(<span class="hljs-string">'fs-extra'</span>);
|
36 | <span class="hljs-built_in">require</span>(<span class="hljs-string">'colors'</span>);
|
37 | <span class="hljs-keyword">var</span> path = [];
|
38 | <span class="hljs-keyword">var</span> index = <span class="hljs-number">0</span>;
|
39 | <span class="hljs-keyword">var</span> modules;
|
40 |
|
41 | <span class="hljs-keyword">var</span> prefix = <span class="hljs-string">"denodify('replace',function(require, module, exports, __filename, __dirname, process) {"</span>;
|
42 | <span class="hljs-keyword">var</span> postfix = <span class="hljs-string">"});"</span>;</pre></div></div>
|
43 |
|
44 | </li>
|
45 |
|
46 |
|
47 | <li id="section-2">
|
48 | <div class="annotation">
|
49 |
|
50 | <div class="pilwrap ">
|
51 | <a class="pilcrow" href="#section-2">¶</a>
|
52 | </div>
|
53 | <p>Utility functions to enable use of nodejs modules in the browser. Used in
|
54 | <a href="http://github.com/Michieljoris/html-builder">html-builder</a> and
|
55 | <a href="http://github.com/Michieljoris/bb-server">bb-server</a>.</p>
|
56 |
|
57 | </div>
|
58 |
|
59 | </li>
|
60 |
|
61 |
|
62 | <li id="section-3">
|
63 | <div class="annotation">
|
64 |
|
65 | <div class="pilwrap ">
|
66 | <a class="pilcrow" href="#section-3">¶</a>
|
67 | </div>
|
68 | <h3 id="wrap">wrap</h3>
|
69 |
|
70 | </div>
|
71 |
|
72 | </li>
|
73 |
|
74 |
|
75 | <li id="section-4">
|
76 | <div class="annotation">
|
77 |
|
78 | <div class="pilwrap ">
|
79 | <a class="pilcrow" href="#section-4">¶</a>
|
80 | </div>
|
81 | <p>Wrap a <code>string</code> of a nodejs module with the proper code to enable its use in
|
82 | the browser. Specify the <code>language</code> your nodejs module is written in to match
|
83 | the added code to the code of the module. Defaults to javascript.</p>
|
84 |
|
85 | </div>
|
86 |
|
87 | </li>
|
88 |
|
89 |
|
90 | <li id="section-5">
|
91 | <div class="annotation">
|
92 |
|
93 | <div class="pilwrap ">
|
94 | <a class="pilcrow" href="#section-5">¶</a>
|
95 | </div>
|
96 | <p>If you leave 2 lines open at the top of every module wrap will replace the top
|
97 | line with the prefix wrapping code. This way line numbers in your modules will
|
98 | match the line numbers of the javascript file loaded in the browser</p>
|
99 |
|
100 | </div>
|
101 |
|
102 | <div class="content"><div class='highlight'><pre>exports.wrap = <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(moduleid, string)</span> {</span>
|
103 | console.log(<span class="hljs-string">'in nodify.wrap'</span>, moduleid);
|
104 | <span class="hljs-keyword">if</span> (string[<span class="hljs-number">0</span>] === <span class="hljs-string">'\n'</span>) string = string.slice(<span class="hljs-number">1</span>);
|
105 | <span class="hljs-keyword">var</span> newPrefix = prefix.replace(<span class="hljs-regexp">/replace/g</span>, Path.join(<span class="hljs-string">'/'</span>, moduleid));</pre></div></div>
|
106 |
|
107 | </li>
|
108 |
|
109 |
|
110 | <li id="section-6">
|
111 | <div class="annotation">
|
112 |
|
113 | <div class="pilwrap ">
|
114 | <a class="pilcrow" href="#section-6">¶</a>
|
115 | </div>
|
116 | <p>postfix = postfix.replace(/__dirname/, Path.dirname(module));</p>
|
117 |
|
118 | </div>
|
119 |
|
120 | <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> newPrefix + string + postfix;
|
121 | };</pre></div></div>
|
122 |
|
123 | </li>
|
124 |
|
125 |
|
126 | <li id="section-7">
|
127 | <div class="annotation">
|
128 |
|
129 | <div class="pilwrap ">
|
130 | <a class="pilcrow" href="#section-7">¶</a>
|
131 | </div>
|
132 | <h3 id="script">script</h3>
|
133 |
|
134 | </div>
|
135 |
|
136 | </li>
|
137 |
|
138 |
|
139 | <li id="section-8">
|
140 | <div class="annotation">
|
141 |
|
142 | <div class="pilwrap ">
|
143 | <a class="pilcrow" href="#section-8">¶</a>
|
144 | </div>
|
145 | <p>Script to load in your html file before all denodified scripts.</p>
|
146 |
|
147 | </div>
|
148 |
|
149 | <div class="content"><div class='highlight'><pre>exports.script = fs.readFileSync(__dirname + <span class="hljs-string">'/denodify.js'</span>);</pre></div></div>
|
150 |
|
151 | </li>
|
152 |
|
153 |
|
154 | <li id="section-9">
|
155 | <div class="annotation">
|
156 |
|
157 | <div class="pilwrap ">
|
158 | <a class="pilcrow" href="#section-9">¶</a>
|
159 | </div>
|
160 | <h3 id="tags">tags</h3>
|
161 |
|
162 | </div>
|
163 |
|
164 | </li>
|
165 |
|
166 |
|
167 | <li id="section-10">
|
168 | <div class="annotation">
|
169 |
|
170 | <div class="pilwrap ">
|
171 | <a class="pilcrow" href="#section-10">¶</a>
|
172 | </div>
|
173 | <p>Given a main <code>module</code>, parses it for require calls, loads the corresponding
|
174 | module files and recursively parses them. Once all dependencies are found
|
175 | calls the <code>callback</code> with a list of tags that if loaded in the browser in the
|
176 | listed order all dependencies would be fullfilled for each module.</p>
|
177 |
|
178 | </div>
|
179 |
|
180 | </li>
|
181 |
|
182 |
|
183 | <li id="section-11">
|
184 | <div class="annotation">
|
185 |
|
186 | <div class="pilwrap ">
|
187 | <a class="pilcrow" href="#section-11">¶</a>
|
188 | </div>
|
189 | <p>Callback is called with an error if a circular dependency is found or a
|
190 | dependency is found that is not in the <code>www</code> directory, or if any other error
|
191 | occurs.</p>
|
192 |
|
193 | </div>
|
194 |
|
195 | </li>
|
196 |
|
197 |
|
198 | <li id="section-12">
|
199 | <div class="annotation">
|
200 |
|
201 | <div class="pilwrap ">
|
202 | <a class="pilcrow" href="#section-12">¶</a>
|
203 | </div>
|
204 | <ul>
|
205 | <li><code>www</code> : the directory the server’s root.</li>
|
206 | <li><code>parent</code> : the path from <code>www</code> to the main module</li>
|
207 | <li><code>module</code> : the id of the file if you were requiring it (without the js)</li>
|
208 | <li><code>callback</code> : called as <code>callback(err, list)</code>.
|
209 | Return a list of script tags to add to a html file. </li>
|
210 | </ul>
|
211 |
|
212 | </div>
|
213 |
|
214 | <div class="content"><div class='highlight'><pre>exports.tags = <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(www, parent, module, callback, listOnly)</span> {</span>
|
215 | list(www, parent, module, callback, <span class="hljs-literal">false</span>);
|
216 | };</pre></div></div>
|
217 |
|
218 | </li>
|
219 |
|
220 |
|
221 | <li id="section-13">
|
222 | <div class="annotation">
|
223 |
|
224 | <div class="pilwrap ">
|
225 | <a class="pilcrow" href="#section-13">¶</a>
|
226 | </div>
|
227 | <h3 id="list">list</h3>
|
228 |
|
229 | </div>
|
230 |
|
231 | </li>
|
232 |
|
233 |
|
234 | <li id="section-14">
|
235 | <div class="annotation">
|
236 |
|
237 | <div class="pilwrap ">
|
238 | <a class="pilcrow" href="#section-14">¶</a>
|
239 | </div>
|
240 | <p>Same as tags, however returns only the properly ordered list of module ids and
|
241 | corresponding file names.</p>
|
242 |
|
243 | </div>
|
244 |
|
245 | <div class="content"><div class='highlight'><pre>exports.list = <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(www, parent, module, callback, listOnly)</span> {</span>
|
246 | list(www, parent, module, callback, <span class="hljs-literal">true</span>);
|
247 | };
|
248 |
|
249 | exports.debug = <span class="hljs-literal">false</span>;
|
250 |
|
251 | <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">walk</span><span class="hljs-params">(module)</span> {</span>
|
252 | modules[module.id] = module;
|
253 | path.push(module.id);
|
254 | module.index = -<span class="hljs-number">1</span>;
|
255 | module.deps.forEach(<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(d)</span> {</span>
|
256 | d = modules[d.id] || d;
|
257 | <span class="hljs-keyword">if</span> (d.index === <span class="hljs-literal">undefined</span>) walk(d);
|
258 | <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (d.index < <span class="hljs-number">0</span>) {
|
259 | <span class="hljs-keyword">var</span> str = <span class="hljs-string">"Module "</span> + module.id + <span class="hljs-string">" is dependent on module "</span> + d.id +
|
260 | <span class="hljs-string">'. However, module '</span> + d.id + <span class="hljs-string">' is also directly or indirectly dependent on module '</span> +
|
261 | module.id + <span class="hljs-string">".\nDependency path to this point: \n"</span> + path.join(<span class="hljs-string">' relies on \n'</span>) +
|
262 | <span class="hljs-string">' relies on '</span> + d.id;
|
263 | console.log(str.red);
|
264 | }
|
265 | });
|
266 | module.index = index++;
|
267 | path.pop();
|
268 | }
|
269 |
|
270 | <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">endsWith</span><span class="hljs-params">(str, trail)</span> {</span>
|
271 | <span class="hljs-keyword">return</span> (str.substr(str.length-trail.length, str.length-<span class="hljs-number">1</span>) === trail);
|
272 | };
|
273 |
|
274 | <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">trailWith</span><span class="hljs-params">(str, trail)</span> {</span>
|
275 | <span class="hljs-keyword">return</span> str ? (str + (!endsWith(str, trail) ? trail : <span class="hljs-string">''</span>)) : <span class="hljs-literal">undefined</span>;
|
276 | };
|
277 |
|
278 | <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">list</span><span class="hljs-params">(www, parent, id, cb, listOnly)</span> {</span>
|
279 | <span class="hljs-keyword">try</span>
|
280 | { www = Path.resolve(www);
|
281 | parent = Path.resolve(www, parent);
|
282 | debug(<span class="hljs-string">'Resolving: '</span> + id + <span class="hljs-string">' in directory '</span> + parent);
|
283 | <span class="hljs-keyword">var</span> fileName = Path.resolve(parent, trailWith(id, <span class="hljs-string">'.js'</span>));
|
284 | <span class="hljs-keyword">try</span> {
|
285 | fs.statSync(fileName);
|
286 | } <span class="hljs-keyword">catch</span>(e) { cb(e,<span class="hljs-literal">null</span>);
|
287 | <span class="hljs-keyword">return</span>;}
|
288 |
|
289 | required(fileName, {
|
290 | includeSource: <span class="hljs-literal">false</span>
|
291 | }, <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(err, deps)</span> {</span>
|
292 | <span class="hljs-keyword">if</span> (err) <span class="hljs-keyword">throw</span> err;
|
293 | <span class="hljs-keyword">else</span> {
|
294 |
|
295 | modules = [];
|
296 | walk({
|
297 | id: id,
|
298 | filename: fileName,
|
299 | deps: deps,
|
300 | index: -<span class="hljs-number">1</span>
|
301 | });
|
302 | <span class="hljs-keyword">var</span> list = <span class="hljs-built_in">Object</span>.keys(modules).map(<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(m)</span> {</span>
|
303 | m = modules[m];
|
304 | <span class="hljs-keyword">var</span> startWithWwwPath = m.filename.indexOf(www) === <span class="hljs-number">0</span>;
|
305 | <span class="hljs-keyword">if</span> (!startWithWwwPath)
|
306 | <span class="hljs-keyword">throw</span> <span class="hljs-string">'Warning: '</span> + m.id + <span class="hljs-string">' was found outside the www directory ('</span> + www + <span class="hljs-string">')'</span>;
|
307 | m.route = m.filename.slice(www.length);
|
308 | debug(<span class="hljs-string">'module:'</span>,m);
|
309 | <span class="hljs-keyword">return</span> m;
|
310 | }).sort(<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(a, b)</span> {</span>
|
311 | <span class="hljs-keyword">return</span> a.index > b.index;
|
312 | }).map(<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(m)</span> {</span>
|
313 | <span class="hljs-keyword">return</span> listOnly ?
|
314 | { id: m.id, route: m.route, filename: m.filename } :
|
315 | <span class="hljs-string">"<script type=\"text/javascript\" src=\""</span> + m.route + <span class="hljs-string">"\"></script>"</span>;
|
316 | });
|
317 | debug(<span class="hljs-string">'Debug:\n'</span>, list);
|
318 | cb(<span class="hljs-literal">null</span>, list);
|
319 | }
|
320 | });
|
321 | } <span class="hljs-keyword">catch</span>(e) {
|
322 | cb(e, <span class="hljs-literal">null</span>);
|
323 | }
|
324 | };
|
325 |
|
326 | <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">debug</span><span class="hljs-params">()</span> {</span>
|
327 | <span class="hljs-keyword">if</span> (exports.debug) console.log.apply(console, <span class="hljs-built_in">arguments</span>);
|
328 | }</pre></div></div>
|
329 |
|
330 | </li>
|
331 |
|
332 |
|
333 | <li id="section-15">
|
334 | <div class="annotation">
|
335 |
|
336 | <div class="pilwrap ">
|
337 | <a class="pilcrow" href="#section-15">¶</a>
|
338 | </div>
|
339 | <p>list(‘../‘, ‘./test’, ‘./m3’, function(err, tags) {
|
340 | console.log();
|
341 | console.log(tags);
|
342 | }, true);</p>
|
343 |
|
344 | </div>
|
345 |
|
346 | </li>
|
347 |
|
348 | </ul>
|
349 | </div>
|
350 | </body>
|
351 | </html>
|