Mercurial > hg > nginx-site
comparison xml/en/docs/njs/node_modules.xml @ 2576:4c8d0b37932d
Corrected syntax and style of "Using node modules with njs".
author | Yaroslav Zhuravlev <yar@nginx.com> |
---|---|
date | Thu, 06 Aug 2020 14:46:58 +0100 |
parents | bda080989b6c |
children | fca42223b9fc |
comparison
equal
deleted
inserted
replaced
2575:2839ad72d8ef | 2576:4c8d0b37932d |
---|---|
7 <!DOCTYPE article SYSTEM "../../../../dtd/article.dtd"> | 7 <!DOCTYPE article SYSTEM "../../../../dtd/article.dtd"> |
8 | 8 |
9 <article name="Using node modules with njs" | 9 <article name="Using node modules with njs" |
10 link="/en/docs/njs/node_modules.html" | 10 link="/en/docs/njs/node_modules.html" |
11 lang="en" | 11 lang="en" |
12 rev="3"> | 12 rev="4"> |
13 | 13 |
14 <section id="intro" name="Introduction"> | 14 <section id="intro"> |
15 | 15 |
16 <para> | 16 <para> |
17 Often, a developer wants to use 3rd-party code, usually available as a library | 17 Often, a developer wants to use 3rd-party code, |
18 of some kind. | 18 usually available as a library of some kind. |
19 In the Javascript world, the concept of a module is relatively new, so there | 19 In the JavaScript world, the concept of a module is relatively new, |
20 was no standard until recently. | 20 so there was no standard until recently. |
21 Many platforms (browsers) still don't support modules, which makes code | 21 Many platforms (browsers) still don't support modules, which makes code |
22 reuse harder. | 22 reuse harder. |
23 The njs does not (yet) support modules, too. | 23 This article describes ways to reuse |
24 This article describes ways to overcome this limitation, using the | 24 <link url="https://nodejs.org/">Node.js</link> code in njs. |
25 <link url="https://nodejs.org/">Node.js</link> ecosystem as an example. | |
26 </para> | 25 </para> |
27 | 26 |
28 <note> | 27 <note> |
29 Examples in this article use features that appeared in | 28 Examples in this article use features that appeared in |
30 <link doc="index.xml">njs</link> | 29 <link doc="index.xml">njs</link> |
31 <link doc="changes.xml" id="njs0.3.8">0.3.8</link> | 30 <link doc="changes.xml" id="njs0.3.8">0.3.8</link> |
32 </note> | 31 </note> |
33 | 32 |
34 <para> | 33 <para> |
35 There is a number of issues that may arise when 3rd-party code is added to njs: | 34 There is a number of issues |
35 that may arise when 3rd-party code is added to njs: | |
36 | 36 |
37 <list type="bullet"> | 37 <list type="bullet"> |
38 | 38 |
39 <listitem>Multiple files that reference each other, and their | 39 <listitem> |
40 dependencies</listitem> | 40 Multiple files that reference each other and their dependencies |
41 | 41 </listitem> |
42 <listitem>Platform-specific APIs</listitem> | 42 |
43 | 43 <listitem> |
44 <listitem>Modern standard language constructions</listitem> | 44 Platform-specific APIs |
45 </listitem> | |
46 | |
47 <listitem> | |
48 Modern standard language constructions | |
49 </listitem> | |
45 | 50 |
46 </list> | 51 </list> |
47 | 52 </para> |
48 </para> | 53 |
49 | 54 <para> |
50 <para> | 55 The good news is that such problems are not something new or specific to njs. |
51 The good news is that such problems are not something new or | 56 JavaScript developers face them daily |
52 specific to njs. | 57 when trying to support multiple disparate platforms |
53 Javascript developers face them daily when trying to support multiple | 58 with very different properties. |
54 disparate platforms with very different properties. | |
55 There are instruments designed to resolve the above-mentioned issues. | 59 There are instruments designed to resolve the above-mentioned issues. |
56 </para> | |
57 | |
58 <para> | |
59 | 60 |
60 <list type="bullet"> | 61 <list type="bullet"> |
61 | 62 |
62 <listitem> | 63 <listitem> |
63 Multiple files that reference each other, and their dependencies | 64 Multiple files that reference each other, and their dependencies |
72 </listitem> | 73 </listitem> |
73 | 74 |
74 <listitem> | 75 <listitem> |
75 Platform-specific APIs | 76 Platform-specific APIs |
76 <para> | 77 <para> |
77 You can use multiple libraries that implement such APIs in a platform-agnostic | 78 You can use multiple libraries that implement such APIs |
78 manner (at the expense of performance, though). | 79 in a platform-agnostic manner (at the expense of performance, though). |
79 Particular features can also be implemented using the | 80 Particular features can also be implemented using the |
80 <link url="https://polyfill.io/v3/">polyfill</link> approach. | 81 <link url="https://polyfill.io/v3/">polyfill</link> approach. |
81 </para> | 82 </para> |
82 </listitem> | 83 </listitem> |
83 | 84 |
84 <listitem> | 85 <listitem> |
85 Modern standard language constructions | 86 Modern standard language constructions |
86 <para> | 87 <para> |
87 Such code can be transpiled: this means performing a number of transformations | 88 Such code can be transpiled: |
89 this means performing a number of transformations | |
88 that rewrite newer language features in accordance with an older standard. | 90 that rewrite newer language features in accordance with an older standard. |
89 For example, <link url="https://babeljs.io/"> babel</link> project can | 91 For example, <link url="https://babeljs.io/"> babel</link> project |
90 be used to this purpose. | 92 can be used to this purpose. |
91 </para> | 93 </para> |
92 </listitem> | 94 </listitem> |
93 | 95 |
94 </list> | 96 </list> |
95 | 97 </para> |
96 </para> | |
97 | |
98 | 98 |
99 <para> | 99 <para> |
100 In this guide, we will use two relatively large npm-hosted libraries: | 100 In this guide, we will use two relatively large npm-hosted libraries: |
101 | 101 |
102 <list type="bullet"> | 102 <list type="bullet"> |
103 | 103 |
104 <listitem> | 104 <listitem> |
105 <link url="https://www.npmjs.com/package/protobufjs">protobufjs</link> - | 105 <link url="https://www.npmjs.com/package/protobufjs">protobufjs</link>— |
106 a library for creating and parsing protobuf messages used by the | 106 a library for creating and parsing protobuf messages used by the |
107 <link url="https://grpc.io/">gRPC</link> protocol. | 107 <link url="https://grpc.io/">gRPC</link> protocol |
108 | 108 </listitem> |
109 </listitem> | 109 |
110 | 110 <listitem> |
111 <listitem> | 111 <link url="https://www.npmjs.com/package/dns-packet">dns-packet</link>— |
112 <link url="https://www.npmjs.com/package/dns-packet">dns-packet</link> - | 112 a library for processing DNS protocol packets |
113 a library for processing DNS protocol packets. | |
114 </listitem> | 113 </listitem> |
115 | 114 |
116 </list> | 115 </list> |
117 | |
118 </para> | 116 </para> |
119 | 117 |
120 </section> | 118 </section> |
121 | 119 |
120 | |
122 <section id="environment" name="Environment"> | 121 <section id="environment" name="Environment"> |
123 | 122 |
124 <para> | 123 <para> |
125 | |
126 <note> | 124 <note> |
127 This document mostly employs a generic approach and AVOIDS specific best | 125 This document mostly employs a generic approach |
128 practice advices concerning Node.js and the rapidly evolving JavaScript | 126 and avoids specific best practice advices concerning Node.js |
129 ecosystem. | 127 and JavaScript. |
130 Make sure to consult the corresponding package's manual BEFORE following the | 128 Make sure to consult the corresponding package's manual |
131 steps suggested here. | 129 before following the steps suggested here. |
132 </note> | 130 </note> |
133 | |
134 First (assuming Node.js is installed and operational), let's create an | 131 First (assuming Node.js is installed and operational), let's create an |
135 empty project and install some dependencies; the commands below assume we're | 132 empty project and install some dependencies; |
136 in the working directory: | 133 the commands below assume we are in the working directory: |
137 | |
138 <example> | 134 <example> |
139 $ mkdir my_project && cd my_project | 135 $ mkdir my_project && cd my_project |
140 $ npx license choose_your_license_here > LICENSE | 136 $ npx license choose_your_license_here > LICENSE |
141 $ npx gitignore node | 137 $ npx gitignore node |
142 | 138 |
160 </example> | 156 </example> |
161 </para> | 157 </para> |
162 | 158 |
163 </section> | 159 </section> |
164 | 160 |
161 | |
165 <section id="protobuf" name="Protobufjs"> | 162 <section id="protobuf" name="Protobufjs"> |
166 | 163 |
167 <para> | 164 <para> |
168 The library provides a parser for the <literal>.proto</literal> interface | 165 The library provides a parser |
169 definitions and a code generator for message parsing and generation. | 166 for the <literal>.proto</literal> interface definitions |
167 and a code generator for message parsing and generation. | |
170 </para> | 168 </para> |
171 | 169 |
172 <para> | 170 <para> |
173 In this example, we will use the | 171 In this example, we will use the |
174 <link url="https://github.com/grpc/grpc/blob/master/examples/protos/helloworld.proto">helloworld.proto</link> | 172 <link url="https://github.com/grpc/grpc/blob/master/examples/protos/helloworld.proto">helloworld.proto</link> |
175 file from the gRPC examples. | 173 file |
176 Our goal is to create two messages: <literal>HelloRequest</literal> and | 174 from the gRPC examples. |
175 Our goal is to create two messages: | |
176 <literal>HelloRequest</literal> and | |
177 <literal>HelloResponse</literal>. | 177 <literal>HelloResponse</literal>. |
178 We will use the | 178 We will use the |
179 <link url="https://github.com/protobufjs/protobuf.js/blob/master/README.md#reflection-vs-static-code">static</link> | 179 <link url="https://github.com/protobufjs/protobuf.js/blob/master/README.md#reflection-vs-static-code">static</link> |
180 mode of protobufjs instead of dynamically generating classes, because | 180 mode of protobufjs instead of dynamically generating classes, because |
181 njs doesn't support adding new functions dynamically due to security | 181 njs doesn't support adding new functions dynamically |
182 considerations. | 182 due to security considerations. |
183 </para> | 183 </para> |
184 | 184 |
185 <para> | 185 <para> |
186 Next, the library is installed and javascript code implementing | 186 Next, the library is installed and |
187 message marshalling is generated from the protocol definition: | 187 the JavaScript code implementing message marshalling |
188 is generated from the protocol definition: | |
188 <example> | 189 <example> |
189 $ npm install protobufjs | 190 $ npm install protobufjs |
190 $ npx pbjs -t static-module helloworld.proto > static.js | 191 $ npx pbjs -t static-module helloworld.proto > static.js |
191 </example> | 192 </example> |
192 | 193 </para> |
193 </para> | 194 |
194 | 195 <para> |
195 <para> | 196 Thus, the <literal>static.js</literal> file becomes our new dependency, |
196 Thus, the <literal>static.js</literal> file becomes our new dependency, storing | 197 storing all the code we need to implement message processing. |
197 all the code we need to implement message processing. | |
198 The <literal>set_buffer()</literal> function contains code that uses the | 198 The <literal>set_buffer()</literal> function contains code that uses the |
199 library to create a buffer with the serialized <literal>HelloRequest</literal> | 199 library to create a buffer with the serialized |
200 message. | 200 <literal>HelloRequest</literal> message. |
201 The code resides in the <literal>code.js</literal> file: | 201 The code resides in the <literal>code.js</literal> file: |
202 | |
203 <example> | 202 <example> |
204 var pb = require('./static.js'); | 203 var pb = require('./static.js'); |
205 | 204 |
206 // Example usage of protobuf library: prepare a buffer to send | 205 // Example usage of protobuf library: prepare a buffer to send |
207 function set_buffer(pb) | 206 function set_buffer(pb) |
218 var n = buffer.length; | 217 var n = buffer.length; |
219 | 218 |
220 var frame = new Uint8Array(5 + buffer.length); | 219 var frame = new Uint8Array(5 + buffer.length); |
221 | 220 |
222 frame[0] = 0; // 'compressed' flag | 221 frame[0] = 0; // 'compressed' flag |
223 frame[1] = (n & 0xFF000000) >>> 24; // length: uint32 in network order | 222 frame[1] = (n & 0xFF000000) >>> 24; // length: uint32 in network byte order |
224 frame[2] = (n & 0x00FF0000) >>> 16; | 223 frame[2] = (n & 0x00FF0000) >>> 16; |
225 frame[3] = (n & 0x0000FF00) >>> 8; | 224 frame[3] = (n & 0x0000FF00) >>> 8; |
226 frame[4] = (n & 0x000000FF) >>> 0; | 225 frame[4] = (n & 0x000000FF) >>> 0; |
227 | 226 |
228 frame.set(buffer, 5); | 227 frame.set(buffer, 5); |
234 </example> | 233 </example> |
235 </para> | 234 </para> |
236 | 235 |
237 <para> | 236 <para> |
238 To ensure it works, we execute the code using node: | 237 To ensure it works, we execute the code using node: |
239 | |
240 <example> | 238 <example> |
241 $ node ./code.js | 239 $ node ./code.js |
242 Uint8Array [ | 240 Uint8Array [ |
243 0, 0, 0, 0, 12, 10, | 241 0, 0, 0, 0, 12, 10, |
244 10, 84, 101, 115, 116, 83, | 242 10, 84, 101, 115, 116, 83, |
245 116, 114, 105, 110, 103 | 243 116, 114, 105, 110, 103 |
246 ] | 244 ] |
247 </example> | 245 </example> |
248 | |
249 You can see that this got us a properly encoded <literal>gRPC</literal> frame. | 246 You can see that this got us a properly encoded <literal>gRPC</literal> frame. |
250 Now let's run it with njs: | 247 Now let's run it with njs: |
251 | |
252 <example> | 248 <example> |
253 $ njs ./code.js | 249 $ njs ./code.js |
254 Thrown: | 250 Thrown: |
255 Error: Cannot find module "./static.js" | 251 Error: Cannot find module "./static.js" |
256 at require (native) | 252 at require (native) |
264 or other similar tool. | 260 or other similar tool. |
265 </para> | 261 </para> |
266 | 262 |
267 <para> | 263 <para> |
268 An attempt to process our existing <literal>code.js</literal> file will result | 264 An attempt to process our existing <literal>code.js</literal> file will result |
269 in a bunch of JS code that is supposed to run in a browser, i.e. immediately | 265 in a bunch of JS code that is supposed to run in a browser, |
270 upon loading. | 266 i.e. immediately upon loading. |
271 This isn't something we actually want. | 267 This isn't something we actually want. |
272 Instead, we want to have an exported function that | 268 Instead, we want to have an exported function that |
273 can be referenced from the nginx configuration. | 269 can be referenced from the nginx configuration. |
274 This requires some wrapper code. | 270 This requires some wrapper code. |
275 | |
276 <note> | 271 <note> |
277 In this guide, we use njs cli in all examples for the sake of simplicity. | 272 In this guide, we use |
273 njs <link doc="cli.xml">cli</link> in all examples for the sake of simplicity. | |
278 In real life, you will be using nginx njs module to run your code. | 274 In real life, you will be using nginx njs module to run your code. |
279 </note> | 275 </note> |
280 | |
281 </para> | 276 </para> |
282 | 277 |
283 <para> | 278 <para> |
284 The <literal>load.js</literal> file contains the library-loading code that | 279 The <literal>load.js</literal> file contains the library-loading code that |
285 stores its handle in the global namespace: | 280 stores its handle in the global namespace: |
290 Our code will be using the "<literal>global.hello</literal>" handle to access | 285 Our code will be using the "<literal>global.hello</literal>" handle to access |
291 the library. | 286 the library. |
292 </para> | 287 </para> |
293 | 288 |
294 <para> | 289 <para> |
295 Next, we process it with browserify to get all dependencies into a single file: | 290 Next, we process it with <literal>browserify</literal> |
291 to get all dependencies into a single file: | |
296 <example> | 292 <example> |
297 $ npx browserify load.js -o bundle.js -d | 293 $ npx browserify load.js -o bundle.js -d |
298 </example> | 294 </example> |
299 | 295 The result is a huge file that contains all our dependencies: |
300 The result is huge file that contains all our dependencies: | |
301 | |
302 <example> | 296 <example> |
303 (function(){function...... | 297 (function(){function...... |
304 ... | 298 ... |
305 ... | 299 ... |
306 },{"protobufjs/minimal":9}]},{},[1]) | 300 },{"protobufjs/minimal":9}]},{},[1]) |
307 //# sourceMappingURL.............. | 301 //# sourceMappingURL.............. |
308 </example> | 302 </example> |
309 | |
310 To get final "<literal>njs_bundle.js</literal>" file we concatenate | 303 To get final "<literal>njs_bundle.js</literal>" file we concatenate |
311 "<literal>bundle.js</literal>" and the following code: | 304 "<literal>bundle.js</literal>" and the following code: |
312 | |
313 <example> | 305 <example> |
314 // Example usage of protobuf library: prepare a buffer to send | 306 // Example usage of protobuf library: prepare a buffer to send |
315 function set_buffer(pb) | 307 function set_buffer(pb) |
316 { | 308 { |
317 // set fields of gRPC payload | 309 // set fields of gRPC payload |
326 var n = buffer.length; | 318 var n = buffer.length; |
327 | 319 |
328 var frame = new Uint8Array(5 + buffer.length); | 320 var frame = new Uint8Array(5 + buffer.length); |
329 | 321 |
330 frame[0] = 0; // 'compressed' flag | 322 frame[0] = 0; // 'compressed' flag |
331 frame[1] = (n & 0xFF000000) >>> 24; // length: uint32 in network order | 323 frame[1] = (n & 0xFF000000) >>> 24; // length: uint32 in network byte order |
332 frame[2] = (n & 0x00FF0000) >>> 16; | 324 frame[2] = (n & 0x00FF0000) >>> 16; |
333 frame[3] = (n & 0x0000FF00) >>> 8; | 325 frame[3] = (n & 0x0000FF00) >>> 8; |
334 frame[4] = (n & 0x000000FF) >>> 0; | 326 frame[4] = (n & 0x000000FF) >>> 0; |
335 | 327 |
336 frame.set(buffer, 5); | 328 frame.set(buffer, 5); |
346 | 338 |
347 // call the code | 339 // call the code |
348 var frame = setbuf(); | 340 var frame = setbuf(); |
349 console.log(frame); | 341 console.log(frame); |
350 </example> | 342 </example> |
351 | |
352 Let's run the file using node to make sure things still work: | 343 Let's run the file using node to make sure things still work: |
353 <example> | 344 <example> |
354 $ node ./njs_bundle.js | 345 $ node ./njs_bundle.js |
355 Uint8Array [ | 346 Uint8Array [ |
356 0, 0, 0, 0, 12, 10, | 347 0, 0, 0, 0, 12, 10, |
357 10, 84, 101, 115, 116, 83, | 348 10, 84, 101, 115, 116, 83, |
358 116, 114, 105, 110, 103 | 349 116, 114, 105, 110, 103 |
359 ] | 350 ] |
360 </example> | 351 </example> |
361 | |
362 Now let's proceed further with njs: | 352 Now let's proceed further with njs: |
363 | |
364 <example> | 353 <example> |
365 $ /njs ./njs_bundle.js | 354 $ /njs ./njs_bundle.js |
366 Uint8Array [0,0,0,0,12,10,10,84,101,115,116,83,116,114,105,110,103] | 355 Uint8Array [0,0,0,0,12,10,10,84,101,115,116,83,116,114,105,110,103] |
367 </example> | 356 </example> |
368 | |
369 The last thing will be to use njs-specific API to convert | 357 The last thing will be to use njs-specific API to convert |
370 array into byte string, so it could be usable by nginx module. | 358 array into byte string, so it could be usable by nginx module. |
371 We can add the following snippet before the last line: | 359 We can add the following snippet before the last line: |
372 <example> | 360 <example> |
373 if (global.njs) { | 361 if (global.njs) { |
374 return String.bytesFrom(frame) | 362 return String.bytesFrom(frame) |
375 } | 363 } |
376 </example> | 364 </example> |
377 | |
378 Finally, we got it working: | 365 Finally, we got it working: |
379 | |
380 <example> | 366 <example> |
381 $ njs ./njs_bundle.js |hexdump -C | 367 $ njs ./njs_bundle.js |hexdump -C |
382 00000000 00 00 00 00 0c 0a 0a 54 65 73 74 53 74 72 69 6e |.......TestStrin| | 368 00000000 00 00 00 00 0c 0a 0a 54 65 73 74 53 74 72 69 6e |.......TestStrin| |
383 00000010 67 0a |g.| | 369 00000010 67 0a |g.| |
384 00000012 | 370 00000012 |
416 </example> | 402 </example> |
417 </para> | 403 </para> |
418 | 404 |
419 </section> | 405 </section> |
420 | 406 |
407 | |
421 <section id="dnspacket" name="DNS-packet"> | 408 <section id="dnspacket" name="DNS-packet"> |
422 | 409 |
423 <para> | 410 <para> |
424 This example uses a library for generation and parsing of DNS packets. | 411 This example uses a library for generation and parsing of DNS packets. |
425 This a case worth considering because the library and its dependencies | 412 This a case worth considering because the library and its dependencies |
433 $ npm install @babel/core @babel/cli @babel/preset-env babel-loader | 420 $ npm install @babel/core @babel/cli @babel/preset-env babel-loader |
434 $ npm install webpack webpack-cli | 421 $ npm install webpack webpack-cli |
435 $ npm install buffer | 422 $ npm install buffer |
436 $ npm install dns-packet | 423 $ npm install dns-packet |
437 </example> | 424 </example> |
438 | |
439 The configuration file, webpack.config.js: | 425 The configuration file, webpack.config.js: |
440 <example> | 426 <example> |
441 const path = require('path'); | 427 const path = require('path'); |
442 | 428 |
443 module.exports = { | 429 module.exports = { |
468 }; | 454 }; |
469 </example> | 455 </example> |
470 Note we are using "<literal>production</literal>" mode. | 456 Note we are using "<literal>production</literal>" mode. |
471 In this mode webpack does not use "<literal>eval</literal>" construction | 457 In this mode webpack does not use "<literal>eval</literal>" construction |
472 not supported by njs. | 458 not supported by njs. |
473 | |
474 The referenced <literal>load.js</literal> file is our entry point: | 459 The referenced <literal>load.js</literal> file is our entry point: |
475 <example> | 460 <example> |
476 global.dns = require('dns-packet') | 461 global.dns = require('dns-packet') |
477 global.Buffer = require('buffer/').Buffer | 462 global.Buffer = require('buffer/').Buffer |
478 </example> | 463 </example> |
479 | |
480 We start the same way, by producing a single file for the libraries: | 464 We start the same way, by producing a single file for the libraries: |
481 | |
482 <example> | 465 <example> |
483 $ npx browserify load.js -o bundle.js -d | 466 $ npx browserify load.js -o bundle.js -d |
484 </example> | 467 </example> |
485 | |
486 Next, we process the file with webpack, which itself invokes babel: | 468 Next, we process the file with webpack, which itself invokes babel: |
487 | |
488 <example> | 469 <example> |
489 $ npx webpack --config webpack.config.js | 470 $ npx webpack --config webpack.config.js |
490 </example> | 471 </example> |
491 | |
492 This command produces the <literal>dist/wp_out.js</literal> file, which is a | 472 This command produces the <literal>dist/wp_out.js</literal> file, which is a |
493 transpiled version of <literal>bundle.js</literal>. | 473 transpiled version of <literal>bundle.js</literal>. |
494 | |
495 We need to concatenate it with <literal>code.js</literal> | 474 We need to concatenate it with <literal>code.js</literal> |
496 that stores our code: | 475 that stores our code: |
497 | |
498 <example> | 476 <example> |
499 function set_buffer(dnsPacket) | 477 function set_buffer(dnsPacket) |
500 { | 478 { |
501 // create DNS packet bytes | 479 // create DNS packet bytes |
502 var buf = dnsPacket.encode({ | 480 var buf = dnsPacket.encode({ |
510 }) | 488 }) |
511 | 489 |
512 return buf; | 490 return buf; |
513 } | 491 } |
514 </example> | 492 </example> |
515 | |
516 Note that in this example generated code is not wrapped into function and we | 493 Note that in this example generated code is not wrapped into function and we |
517 do not need to call it explicitly. | 494 do not need to call it explicitly. |
518 The result is in the "<literal>dist</literal>" directory: | 495 The result is in the "<literal>dist</literal>" directory: |
519 | |
520 <example> | 496 <example> |
521 $ cat dist/wp_out.js code.js > njs_dns_bundle.js | 497 $ cat dist/wp_out.js code.js > njs_dns_bundle.js |
522 </example> | 498 </example> |
523 | |
524 Let's call our code at the end of a file: | 499 Let's call our code at the end of a file: |
525 <example> | 500 <example> |
526 var b = setbuf(1); | 501 var b = setbuf(1); |
527 console.log(b); | 502 console.log(b); |
528 </example> | 503 </example> |
529 | |
530 And execute it using node: | 504 And execute it using node: |
531 | |
532 <example> | 505 <example> |
533 $ node ./njs_dns_bundle_final.js | 506 $ node ./njs_dns_bundle_final.js |
534 Buffer [Uint8Array] [ | 507 Buffer [Uint8Array] [ |
535 0, 1, 1, 0, 0, 1, 0, 0, | 508 0, 1, 1, 0, 0, 1, 0, 0, |
536 0, 0, 0, 0, 6, 103, 111, 111, | 509 0, 0, 0, 0, 6, 103, 111, 111, |
537 103, 108, 101, 3, 99, 111, 109, 0, | 510 103, 108, 101, 3, 99, 111, 109, 0, |
538 0, 1, 0, 1 | 511 0, 1, 0, 1 |
539 ] | 512 ] |
540 </example> | 513 </example> |
541 | |
542 Make sure this works as expected, and then run it with njs: | 514 Make sure this works as expected, and then run it with njs: |
543 <example> | 515 <example> |
544 $ njs ./njs_dns_bundle_final.js | 516 $ njs ./njs_dns_bundle_final.js |
545 Uint8Array [0,1,1,0,0,1,0,0,0,0,0,0,6,103,111,111,103,108,101,3,99,111,109,0,0,1,0,1] | 517 Uint8Array [0,1,1,0,0,1,0,0,0,0,0,0,6,103,111,111,103,108,101,3,99,111,109,0,0,1,0,1] |
546 </example> | 518 </example> |
561 var resolved_name = packet.answers[0].name; | 533 var resolved_name = packet.answers[0].name; |
562 | 534 |
563 // expected name is 'google.com', according to our request above | 535 // expected name is 'google.com', according to our request above |
564 } | 536 } |
565 </example> | 537 </example> |
566 | |
567 </para> | 538 </para> |
568 | 539 |
569 </section> | 540 </section> |
570 | 541 |
571 </article> | 542 </article> |