/
nodejs_handbook.md
5365 lines (3688 loc) · 171 KB
/
nodejs_handbook.md
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#### Table of Contents
- [Introduction to Node.js](https://medium.com/p/6912378afc6e#0a66)
- [A brief history of Node.js](https://medium.com/p/6912378afc6e#bc80)
- [How to install Node.js](https://medium.com/p/6912378afc6e#7af2)
- [How much JavaScript do you need to know to use Node?](https://medium.com/p/6912378afc6e#fadd)
- [Differences between Node and the Browser](https://medium.com/p/6912378afc6e#e35f)
- [The V8 JavaScript Engine](https://medium.com/p/6912378afc6e#a7e7)
- [How to exit from a Node.js program](https://medium.com/p/6912378afc6e#e01b)
- [How to read environment variables from Node.js](https://medium.com/p/6912378afc6e#c84b)
- [Where to host a Node.js app](https://medium.com/p/6912378afc6e#bf2f)
- [How to use the Node.js REPL](https://medium.com/p/6912378afc6e#68bb)
- [Node, accept arguments from the command line](https://medium.com/p/6912378afc6e#d482)
- [Accept input from the command line in Node](https://medium.com/p/6912378afc6e#a358)
- [Expose functionality from a Node file using exports](https://medium.com/p/6912378afc6e#004b)
- [Introduction to npm](https://medium.com/p/6912378afc6e#ed95)
- [Where does npm install the packages?](https://medium.com/p/6912378afc6e#0d78)
- [How to use or execute a package installed using npm](https://medium.com/p/6912378afc6e#aa45)
- [The package.json guide](https://medium.com/p/6912378afc6e#1481)
- [The package-lock.json file](https://medium.com/p/6912378afc6e#c62c)
- [Find the installed version of an npm package](https://medium.com/p/6912378afc6e#0afa)
- [Install an older version of an npm package](https://medium.com/p/6912378afc6e#a820)
- [Update all the Node dependencies to their latest version](https://medium.com/p/6912378afc6e#4c5e)
- [Semantic Versioning using npm](https://medium.com/p/6912378afc6e#903b)
- [Uninstalling npm packages](https://medium.com/p/6912378afc6e#bf88)
- [npm global or local packages](https://medium.com/p/6912378afc6e#2ab7)
- [npm dependencies and devDependencies](https://medium.com/p/6912378afc6e#0a6a)
- [The npx Node Package Runner](https://medium.com/p/6912378afc6e#5d12)
- [The Event Loop](https://medium.com/p/6912378afc6e#47b1)
- [Understanding process.nextTick()](https://medium.com/p/6912378afc6e#4720)
- [Understanding setImmediate()](https://medium.com/p/6912378afc6e#577f)
- [Timers](https://medium.com/p/6912378afc6e#29a5)
- [Asynchronous Programming and Callbacks](https://medium.com/p/6912378afc6e#a0f1)
- [Promises](https://medium.com/p/6912378afc6e#8eeb)
- [Async and Await](https://medium.com/p/6912378afc6e#bbd6)
- [The Node Event emitter](https://medium.com/p/6912378afc6e#c10c)
- [How HTTP requests work](https://medium.com/p/6912378afc6e#bdce)
- [The HTTP protocol](https://medium.com/p/6912378afc6e#c095)
- [Build an HTTP Server](https://medium.com/p/6912378afc6e#adef)
- [Making HTTP requests with Node](https://medium.com/p/6912378afc6e#880e)
- [HTTP requests in Node using Axios](https://medium.com/p/6912378afc6e#b1a5)
- [Using WebSockets in Node.js](https://medium.com/p/6912378afc6e#e69d)
- [Working with file descriptors in Node](https://medium.com/p/6912378afc6e#09c4)
- [Node file stats](https://medium.com/p/6912378afc6e#5772)
- [Node File Paths](https://medium.com/p/6912378afc6e#5254)
- [Reading files with Node](https://medium.com/p/6912378afc6e#84f3)
- [Writing files with Node](https://medium.com/p/6912378afc6e#cc04)
- [Working with folders in Node](https://medium.com/p/6912378afc6e#7357)
- [The Node fs module](https://medium.com/p/6912378afc6e#72c5)
- [The Node path module](https://medium.com/p/6912378afc6e#4307)
- [The Node os module](https://medium.com/p/6912378afc6e#db0e)
- [The Node events module](https://medium.com/p/6912378afc6e#0239)
- [The Node http module](https://medium.com/p/6912378afc6e#a843)
- [Node.js Streams](https://medium.com/p/6912378afc6e#353b)
- [The basics of working with MySQL and Node](https://medium.com/p/6912378afc6e#36a4)
- [The difference between development and production](https://medium.com/p/6912378afc6e#c667)
### Introduction to Node.js
This handbook is a getting started guide to Node.js, the server-side JavaScript runtime environment.
#### Overview
Node.js is a **runtime environment for JavaScript** that runs on the **server**.
Node.js is an open source cross-platform. Since its introduction in 2009, it got hugely popular and now plays a significant role in the web development scene. If GitHub stars are one popularity indication factor, having 46,000+ stars means it is very popular.
Node.js is built on top of the Google Chrome V8 JavaScript engine, and it’s mainly used to create web servers — but it’s not limited to that.
#### It’s fast
One of the main selling points of Node.js is **speed**. JavaScript code running on Node.js (depending on the benchmark) can be twice as fast as compiled languages like C or Java, and orders of magnitude faster than interpreted languages like Python or Ruby, because of its non-blocking paradigm.
#### It’s simple
Node.js is simple. Extremely simple, actually.
#### It’s JavaScript
Node.js runs JavaScript code. This means that millions of front-end developers that already use JavaScript in the browser are able to run the server-side code and client-side code using the same programming language without the need to learn a completely different tool.
The paradigms are all the same, and in Node.js the new ECMAScript standards can be used first, as you don’t have to wait for all your users to update their browsers — you decide which ECMAScript version to use by changing the Node.js version.
#### It runs on V8
Running on the Google V8 JavaScript engine, which is open source — Node.js is able to leverage the work of thousands of engineers that made (and will continue to make) the Chrome JavaScript runtime blazing fast.
#### It’s an asynchronous platform
In traditional programming languages (C, Java, Python, PHP) all instructions are blocking by default unless you explicitly “opt in” to perform asynchronous operations. If you perform a network request to read some JSON, the execution of that particular thread is blocked until the response is ready.
JavaScript allows to create **asynchronous and non-blocking code** in a very simple way, by using a single thread, callback functions and event-driven programming. Every time an expensive operation occurs, we pass a callback function that will be called once we can continue with the processing. We’re not waiting for that to finish before going on with the rest of the program.
Such mechanism derives from the browser. We can’t wait until something loads from an AJAX request before being able to intercept click events on the page. **It all must happen in real time** to provide a good experience to the user.
If you’ve created an onclick handler for a web page you’ve already used asynchronous programming techniques with event listeners.
This allows Node.js to handle thousands of concurrent connections with a single server without introducing the burden of managing threads concurrency, which would be a major source of bugs.
Node provides non-blocking I/O primitives, and generally, libraries in Node.js are written using non-blocking paradigms, making a blocking behavior an exception rather than the normal.
When Node.js needs to perform an I/O operation, like reading from the network, access a database or the filesystem, instead of blocking the thread Node.js will simply resume the operations when the response comes back, instead of wasting CPU cycles waiting.
#### It has a huge number of libraries
With its simple structure, the node package manager ([npm](https://flaviocopes.com/npm/)) helped the ecosystem of Node.js proliferate. Now the [npm registry](https://www.npmjs.com/) hosts almost 500,000 open source packages you can freely use.
### A sample Node.js application
The most common example Hello World of Node.js is a web server:
```
const http = require('http')
const hostname = '127.0.0.1'
const port = 3000
const server = http.createServer((req, res) => {
res.statusCode = 200
res.setHeader('Content-Type', 'text/plain')
res.end('Hello World\n')
})
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`)
})
```
To run this snippet, save it as a `server.js` file and run `node server.js` in your terminal.
This code first includes the Node.js `http` [module](https://nodejs.org/api/http.html).
Node.js has an amazing [standard library](https://nodejs.org/api/), including a first-class support for networking.
The `createServer()` method of `http` creates a new HTTP server and returns it.
The server is set to listen on the specified port and hostname. When the server is ready, the callback function is called, in this case informing us that the server is running.
Whenever a new request is received, the `request` [event](https://nodejs.org/api/http.html#http_event_request) is called, providing two objects: a request (an `http.IncomingMessage`object) and a response (an `http.ServerResponse`object).
These 2 objects are essential to handle the HTTP call.
The first provides the request details. In this simple example, this is not used, but you could access the request headers and request data.
The second is used to return data to the caller.
In this case with:
```
res.statusCode = 200
```
We set the `statusCode` property to `200`, to indicate a successful response.
We set the Content-Type header:
```
res.setHeader('Content-Type', 'text/plain')
```
…and we end close the response, adding the content as an argument to `end()`:
```
res.end('Hello World\n')
```
### Node.js frameworks and tools
Node.js is a low-level platform. To make things easier and more interesting for developers, thousands of libraries were built upon Node.js.
Many of those established over time as popular options. Here is a non-comprehensive list to the ones I consider very relevant and worth learning:
- [**Express**](https://expressjs.com/)One of the most simple yet powerful ways to create a web server. Its minimalist approach and unopinionated focus on the core features of a server is key to its success.
- [**Meteor**](https://flaviocopes.com/meteor/)An incredibly powerful full-stack framework, empowering you with an isomorphic approach to building apps with JavaScript and sharing code on the client and the server. Once an off-the-shelf tool that provided everything, it now integrates with front-end libraries such as [React](https://flaviocopes.com/react/), [Vue](https://flaviocopes.com/vue-introduction/)and [Angular](https://angularjs.org/). Meteor can be used to create mobile apps as well.
- [**Koa**](http://koajs.com/)Built by the same team behind Express, Koa aims to be even simpler and smaller, building on top of years of knowledge. The new project was born out of the need to create incompatible changes without disrupting the existing community.
- [**Next.js**](https://flaviocopes.com/nextjs/)This is a framework to render server-side rendered [React](https://reactjs.org/) applications.
- [**Micro**](https://github.com/zeit/micro)This is a very lightweight server to create asynchronous HTTP microservices.
- [**Socket.io**](https://socket.io/)This is a real-time communication engine to build network applications.
### A brief history of Node.js
#### A look back on the history of Node.js from 2009 to today
Believe it or not, Node.js is just 9 years old.
In comparison, JavaScript is 23 years old and the web as we know it (after the introduction of Mosaic) is 25 years old.
9 years is such a little amount of time for a technology, but Node.js seems to have been around forever.
I’ve had the pleasure to work with Node.js since the early days when it was just 2 years old, and despite the little information available, you could already feel it was a huge thing.
In this section, I want to draw the big picture of Node.js in its history, to put things in perspective.
#### A little bit of history
JavaScript is a programming language that was created at Netscape as a scripting tool to manipulate web pages inside their browser, [Netscape Navigator](https://en.wikipedia.org/wiki/Netscape_Navigator).
Part of the business model of Netscape was to sell Web Servers, which included an environment called “Netscape LiveWire”, which could create dynamic pages using server-side JavaScript. So the idea of server-side JavaScript was not introduced by Node.js, it’s old just like JavaScript — but at the time it was not successful.
One key factor that led to the rise of Node.js was timing. A few years ago, JavaScript was starting to be considered a serious language, thanks for the “Web 2.0” applications that showed the world what a modern experience on the web could be like (think Google Maps or GMail).
The JavaScript engines performance bar raised considerably thanks to the browser competition battle, which is still going strong. Development teams behind each major browser work hard every day to give us better performance, which is a huge win for JavaScript as a platform. Chrome V8, the engine that Node.js uses under the hood, is one of those and in particular it’s the Chrome JavaScript engine.
But of course, Node.js is not popular just because of pure luck or timing. It introduced much innovative thinking on how to program in JavaScript on the server.
#### 2009
Node.js is born
The first form of [npm](https://flaviocopes.com/npm/) is created
#### 2010
[Express](https://flaviocopes.com/express/) is born
[Socket.io](https://socket.io/) is born
#### 2011
npm hits 1.0
Big companies start adopting Node: [LinkedIn](https://www.linkedin.com/), [Uber](https://www.uber.com/)
[Hapi](https://hapijs.com/) is born
#### 2012
Adoption continues very rapidly
#### 2013
First big blogging platform using Node.js: [Ghost](https://ghost.org/)
[Koa](https://koajs.com/) is born
#### 2014
Big drama: [IO.js](https://iojs.org/) is a major fork of Node.js, with the goal of introducing ES6 support and move faster
#### 2015
The [Node.js Foundation](https://foundation.nodejs.org/) is born
IO.js is merged back into Node.js
npm introduces private modules
[Node 4](https://nodejs.org/en/blog/release/v4.0.0/) (no 1, 2, 3 versions were previously released)
#### 2016
The [leftpad incident](https://blog.npmjs.org/post/141577284765/kik-left-pad-and-npm)
[Yarn](https://flaviocopes.com/yarn/) is born: Node 6
#### 2017
npm focuses more on security: Node 8
[HTTP/2](https://nodejs.org/api/http2.html)
[V8](https://flaviocopes.com/v8/) introduces Node in its testing suite, officially making Node a target for the JavaScript engine, in addition to Chrome
3 billion npm downloads every week
#### 2018
Node 10
[ES modules](https://flaviocopes.com/es-modules/).
[mjs](https://nodejs.org/api/esm.html) experimental support
### How to install Node.js
#### How you can install Node.js on your system: a package manager, the official website installer or nvm
Node.js can be installed in different ways. This post highlights the most common and convenient ones.
Official packages for all the major platforms are available [here](https://nodejs.org/en/download/).
One very convenient way to install Node.js is through a package manager. In this case, every operating system has its own.
On macOS, [Homebrew](https://brew.sh/) is the de-facto standard, and — once installed — allows to install Node.js very easily, by running this command in the CLI:
```
brew install node
```
Other package managers for Linux and Windows are listed [here](https://nodejs.org/en/download/package-manager/).
[nvm](https://github.com/creationix/nvm/blob/master/README.md) is a popular way to run Node.js. It allows you to easily switch the Node.js version, and install new versions to try and easily rollback if something breaks, for example.
It is also very useful to test your code with old Node.js versions.
My suggestion is to use the official installer if you are just starting out and you don’t use Homebrew already. Otherwise, Homebrew is my favorite solution.
### How much JavaScript do you need to know to use Node.js?
If you are just starting out with JavaScript, how deeply do you need to know the language?
As a beginner, it’s hard to get to a point where you are confident enough in your programming abilities.
While learning to code, you might also be confused at where does JavaScript end, and where Node.js begins, and vice versa.
I would recommend you to have a good grasp of the main JavaScript concepts before diving into Node.js:
- Lexical Structure
- Expressions
- Types
- Variables
- Functions
- this
- Arrow Functions
- Loops
- Loops and Scope
- Arrays
- Template Literals
- Semicolons
- Strict Mode
- ECMAScript 6, 2016, 2017
With those concepts in mind, you are well on your road to become a proficient JavaScript developer, in both the browser and in Node.js.
The following concepts are also key to understand asynchronous programming, which is one fundamental part of Node.js:
- Asynchronous programming and callbacks
- Timers
- Promises
- Async and Await
- Closures
- The Event Loop
Luckily I wrote a free ebook that explains all those topics, and it’s called [JavaScript Fundamentals](https://flaviocopes.com/javascript/). It’s the most compact resource you’ll find to learn all of this.
### Differences between Node.js and the Browser
How writing JavaScript application in Node.js differs from programming for the Web inside the browser.
Both the browser and Node use JavaScript as their programming language.
Building apps that run in the browser is a completely different thing than building a Node.js application.
Despite the fact that it’s always JavaScript, there are some key differences that make the experience radically different.
A front-end developer that writes Node.js apps has a huge advantage — the language is still the same.
You have a huge opportunity because we know how hard it is to fully, deeply learn a programming language. By using the same language to perform all your work on the web — both on the client and on the server — you’re in a unique position of advantage.
What changes is the ecosystem.
In the browser, most of the time what you are doing is interacting with the DOM, or other Web Platform APIs like Cookies. Those do not exist in Node.js, of course. You don’t have the `document`, `window` and all the other objects that are provided by the browser.
And in the browser, we don’t have all the nice APIs that Node.js provides through its modules, like the file system access functionality.
Another big difference is that in Node.js you control the environment. Unless you are building an open source application that anyone can deploy anywhere, you know which version of Node.js you will run the application on. Compared to the browser environment, where you don’t get the luxury to choose what browser your visitors will use, this is very convenient.
This means that you can write all the modern ES6–7–8–9 JavaScript that your Node version supports.
Since JavaScript moves so fast, but browsers can be a bit slow and users a bit slow to upgrade — sometimes on the web, you are stuck using older JavaScript/ECMAScript releases.
You can use Babel to transform your code to be ES5-compatible before shipping it to the browser, but in Node.js, you won’t need that.
Another difference is that Node.js uses the [CommonJS](https://flaviocopes.com/commonjs/) module system, while in the browser we are starting to see the ES Modules standard being implemented.
In practice, this means that for the time being you use `require()` in Node.js and `import` in the browser.
### The V8 JavaScript Engine
V8 is the name of the JavaScript engine that powers Google Chrome. It’s the thing that takes our JavaScript and executes it while browsing with Chrome.
V8 provides the runtime environment in which JavaScript executes. The DOM, and the other Web Platform APIs are provided by the browser.
The cool thing is that the JavaScript engine is independent by the browser in which it’s hosted. This key feature enabled the rise of Node.js. V8 was chosen for being the engine chosen by Node.js back in 2009, and as the popularity of Node.js exploded, V8 became the engine that now powers an incredible amount of server-side code written in JavaScript.
The Node.js ecosystem is huge and thanks to it V8 also powers desktop apps, with projects like [Electron](https://electronjs.org/).
#### Other JS engines
Other browsers have their own JavaScript engine:
- Firefox has [Spidermonkey](https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey)
- Safari has [JavaScriptCore](https://developer.apple.com/documentation/javascriptcore) (also called Nitro)
- Edge has [Chakra](https://github.com/Microsoft/ChakraCore)
and many others exist as well.
All those engines implement the ECMA ES-262 standard, also called ECMAScript, the standard used by JavaScript.
#### The quest for performance
V8 is written in C++, and it’s continuously improved. It is portable and runs on Mac, Windows, Linux and several other systems.
In this V8 introduction, I will ignore the implementation details of V8. They can be found on more authoritative sites, including the [V8 official site](https://developers.google.com/v8/), and they change over time, often radically.
V8 is always evolving, just like the other JavaScript engines around, to speed up the Web and the Node.js ecosystem.
On the web, there is a race for performance that’s been going on for years, and we (as users and developers) benefit a lot from this competition because we get faster and more optimized machines year after year.
#### Compilation
JavaScript is generally considered an interpreted language, but modern JavaScript engines no longer just interpret JavaScript, they compile it.
This happens since 2009 when the SpiderMonkey JavaScript compiler was added to Firefox 3.5, and everyone followed this idea.
JavScript is internally compiled by V8 with just-in-time (JIT) compilation to speed up the execution.
This might seem counter-intuitive,. But since the introduction of Google Maps in 2004, JavaScript has evolved from a language that was generally executing a few dozens of lines of code to complete applications with thousands to hundreds of thousands of lines running in the browser.
Our applications now can run for hours inside a browser, rather than being just a few form validation rules or simple scripts.
In this **new world**, compiling JavaScript makes perfect sense because while it might take a little bit more to have the JavaScript **ready**, once done it’s going to be much more performant that purely interpreted code.
### How to exit from a Node.js program
There are various ways to terminate a Node.js application.
When running a program in the console you can close it with `ctrl-C`, but what I want to discuss here is programmatically exiting.
Let’s start with the most drastic one, and see why you’re better off **not** using it.
The `process` core module is provides a handy method that allows you to programmatically exit from a Node.js program: `process.exit()`.
When Node.js runs this line, the process is immediately forced to terminate.
This means that any callback that’s pending, any network request still being sent, any file system access, or processes writing to `stdout` or `stderr` — all is going to be ungracefully terminated right away.
If this is fine for you, you can pass an integer that signals the operating system the exit code:
```
process.exit(1)
```
By default the exit code is `0`, which means success. Different exit codes have different meaning, which you might want to use in your own system to have the program communicate to other programs.
You can read more on exit codes [here](https://nodejs.org/api/process.html#process_exit_codes).
You can also set the `process.exitCode` property:
```
process.exitCode = 1
```
and when the program will later end, Node.js will return that exit code.
A program will gracefully exit when all the processing is done.
Many times with Node.js we start servers, like this HTTP server:
```
const express = require('express')
const app = express()
app.get('/', (req, res) => {
res.send('Hi!')
})
app.listen(3000, () => console.log('Server ready'))
```
This program is never going to end. If you call `process.exit()`, any currently pending or running request is going to be aborted. This is **not nice**.
In this case you need to send the command a `SIGTERM` signal, and handle that with the process signal handler:
**Note:** `process` does not require a `require`, it's automatically available.
```
const express = require('express')
const app = express()
app.get('/', (req, res) => {
res.send('Hi!')
})
app.listen(3000, () => console.log('Server ready'))
process.on('SIGTERM', () => {
app.close(() => {
console.log('Process terminated')
})
})
```
What are signals? Signals are a Portable Operating System Interface (POSIX) intercommunication system: a notification sent to a process in order to notify it of an event that occurred.
`SIGKILL` is the signals that tells a process to immediately terminate, and would ideally act like `process.exit()`.
`SIGTERM` is the signals that tells a process to gracefully terminate. It is the signal that's sent from process managers like `upstart` or `supervisord` and many others.
You can send this signal from inside the program, in another function:
```
process.kill(process.pid, 'SIGTERM')
```
Or from another Node.js running program, or any other app running in your system that knows the PID of the process you want to terminate.
### How to read environment variables from Node.js
The `process` core module of Node provides the `env`property which hosts all the environment variables that were set at the moment the process was started.
Here is an example that accesses the `NODE_ENV` environment variable, which is set to `development` by default.
```
process.env.NODE_ENV // "development"
```
Setting it to `production` before the script runs will tell Node.js that this is a production environment.
In the same way you can access any custom environment variable you set.
### Where to host a Node.js app
A Node.js application can be hosted in a lot of places, depending on your needs.
Here is a non-exhaustive list of the options you can explore when you want to deploy your app and make it publicly accessible.
I will list the options from simplest and constrained to more complex and powerful.
#### Simplest option ever: local tunnel
Even if you have a dynamic IP, or you’re under a NAT, you can deploy your app and serve the requests right from your computer using a local tunnel.
This option is suited for some quick testing, demo a product or sharing of an app with a very small group of people.
A very nice tool for this, available on all platforms, is [ngrok](https://ngrok.com/).
Using it, you can just type `ngrok PORT` and the PORT you want is exposed to the internet. You will get a ngrok.io domain, but with a paid subscription you can get a custom URL as well as more security options (remember that you are opening your machine to the public Internet).
Another service you can use is [localtunnel](https://github.com/localtunnel/localtunnel).
#### Zero configuration deployments
#### Glitch
[Glitch](https://glitch.com/) is a playground and a way to build your apps faster than ever, and see them live on their own glitch.com subdomain. You cannot currently have a a custom domain, and there are a few [restrictions](https://glitch.com/faq#restrictions) in place, but it’s really great to prototype. It looks fun (and this is a plus), and it’s not a dumbed down environment — you get all the power of Node.js, a CDN, secure storage for credentials, GitHub import/export and much more.
Provided by the company behind FogBugz and Trello (and co-creators of Stack Overflow).
I use it a lot for demo purposes.
#### Codepen
[Codepen](https://codepen.io/) is an amazing platform and community. You can create a project with multiple files, and deploy it with a custom domain.
#### Serverless
A way to publish your apps, and have no server at all to manage, is Serverless. Serverless is a paradigm where you publish your apps as **functions**, and they respond on a network endpoint (also called FAAS — Functions As A Service).
To very popular solutions are:
- [Serverless Framework](https://serverless.com/framework/)
- [Standard Library](https://stdlib.com/)
They both provide an abstraction layer to publishing on AWS Lambda and other FAAS solutions based on Azure or the Google Cloud offering.
#### PAAS
PAAS stands for Platform As A Service. These platforms take away a lot of things you should otherwise worry about when deploying your application.
#### Zeit Now
[Zeit](https://zeit.co/now) is an interesting option. You just type `now` in your terminal, and it takes care of deploying your application. There is a free version with limitations, and the paid version is more powerful. You simply forget that there’s a server, you just deploy the app.
#### Nanobox
[Nanobox](https://nanobox.io/)
#### Heroku
[Heroku](https://www.heroku.com/) is an amazing platform.
This is a great article on [getting started with Node.js on Heroku](https://devcenter.heroku.com/articles/getting-started-with-node).
#### Microsoft Azure
[Azure](https://azure.microsoft.com/en-us/) is the Microsoft Cloud offering.
Check out how to [create a Node.js web app in Azure](https://docs.microsoft.com/en-us/azure/app-service/app-service-web-get-started-node).
#### Google Cloud Platform
[Google Cloud](https://cloud.google.com/) is an amazing structure for your apps.
They have a good [Node.js Documentation Section](https://cloud.google.com/node/).
#### Virtual Private Server
In this section you find the usual suspects, ordered from more user friendly to less user friendly:
- [Digital Ocean](https://www.digitalocean.com/)
- [Linode](https://www.linode.com/)
- [Amazon Web Services](https://aws.amazon.com/), in particular I mention Amazon Elastic Beanstalk as it abstracts away a little bit the complexity of AWS.
Since they provide an empty Linux machine on which you can work, there is no specific tutorial for these.
There are lots more options in the VPS category, those are just the ones I used and I would recommend.
#### Bare metal
Another solution is to get a [bare metal server](https://en.wikipedia.org/wiki/Bare-metal_server), install a Linux distribution, connect it to the internet (or rent one monthly, like you can do using the [Vultr Bare Metal](https://www.vultr.com/pricing/baremetal/) service)
### How to use the Node.js REPL
REPL stands for Read-Evaluate-Print-Loop, and it’s a great way to explore the Node.js features in a quick way.
The `node` command is the one we use to run our Node.js scripts:
```
node script.js
```
If we omit the filename, we use it in REPL mode:
```
node
```
If you try it now in your terminal, this is what happens:
```
❯ node
>
```
the command stays in idle mode and waits for us to enter something.
**Tip**: if you are unsure how to open your terminal, Google “How to open terminal on <your operating system>”.
The REPL is waiting for us to enter some JavaScript code.
Start simple and enter:
```
> console.log('test')
test
undefined
>
```
The first value, `test`, is the output we told the console to print, then we get undefined which is the return value of running `console.log()`.
We can now enter a new line of JavaScript.
#### Use the tab to autocomplete
The cool thing about the REPL is that it’s interactive.
As you write your code, if you press the `tab` key the REPL will try to autocomplete what you wrote to match a variable you already defined or a predefined one.
#### Exploring JavaScript objects
Try entering the name of a JavaScript class, like `Number`, add a dot and press `tab`.
The REPL will print all the properties and methods you can access on that class:
![img](https://cdn-images-1.medium.com/max/880/1*K2DrlIf5O2cto445HS5eVg.png)
#### Explore global objects
You can inspect the globals you have access to by typing `global.` and pressing `tab`:
![img](https://cdn-images-1.medium.com/max/880/1*wr71LKOT7LM4RsVK80knoQ.png)
#### The _ special variable
If after some code you type `_`, that is going to print the result of the last operation.
#### Dot commands
The REPL has some special commands, all starting with a dot `.`. They are
- `.help`: shows the dot commands help
- `.editor`: enables editor more, to write multiline JavaScript code with ease. Once you are in this mode, enter ctrl-D to run the code you wrote.
- `.break`: when inputting a multi-line expression, entering the .break command will abort further input. Same as pressing ctrl-C.
- `.clear`: resets the REPL context to an empty object and clears any multi-line expression currently being input.
- `.load`: loads a JavaScript file, relative to the current working directory
- `.save`: saves all you entered in the REPL session to a file (specify the filename)
- `.exit`: exists the repl (same as pressing ctrl-C two times)
The REPL knows when you are typing a multi-line statement without the need to invoke `.editor`.
For example if you start typing an iteration like this:
```
[1, 2, 3].forEach(num => {
```
and you press `enter`, the REPL will go to a new line that starts with 3 dots, indicating you can now continue to work on that block.
```
... console.log(num)
... })
```
If you type `.break` at the end of a line, the multiline mode will stop and the statement will not be executed.
### Node.js, accept arguments from the command line
How to accept arguments in a Node.js program passed from the command line
You can pass any number of arguments when invoking a Node.js application using:
```
node app.js
```
Arguments can be standalone or have a key and a value.
For example:
```
node app.js flavio
```
or
```
node app.js name=flavio
```
This changes how you will retrieve this value in the Node.js code.
The way you retrieve it is using the `process` object built into Node.js.
It exposes an `argv` property, which is an array that contains all the command line invocation arguments.
The first argument is the full path of the `node` command.
The second element is the full path of the file being executed.
All the additional arguments are present from the third position going forward.
You can iterate over all the arguments (including the node path and the file path) using a loop:
```
process.argv.forEach((val, index) => {
console.log(`${index}: ${val}`)
})
```
You can get only the additional arguments by creating a new array that excludes the first 2 params:
```
const args = process.argv.slice(2)
```
If you have one argument without an index name, like this:
```
node app.js flavio
```
you can access it using
```
const args = process.argv.slice(2)
args[0]
```
In this case:
```
node app.js name=flavio
```
`args[0]` is `name=flavio`, and you need to parse it. The best way to do so is by using the `minimist` [library](https://www.npmjs.com/package/minimist), which helps dealing with arguments:
```
const args = require('minimist')(process.argv.slice(2))
args['name'] //flavio
```
### Output to the command line using Node.js
How to print to the command line console using Node.js, from the basic console.log to more complex scenarios
#### Basic output using the console module
Node.js provides a `console` [module](https://nodejs.org/api/console.html) which provides tons of very useful ways to interact with the command line.
It is basically the same as the `console` object you find in the browser.
The most basic and most used method is `console.log()`, which prints the string you pass to it to the console.
If you pass an object, it will render it as a string.
You can pass multiple variables to `console.log`, for example:
```
const x = 'x'
const y = 'y'
console.log(x, y)
```
and Node.js will print both.
We can also format pretty phrases by passing variables and a format specifier.
For example:
```
console.log('My %s has %d years', 'cat', 2)
```
- `%s` format a variable as a string
- `%d` or `%i` format a variable as an integer
- `%f` format a variable as a floating point number
- `%O` used to print an object representation
Example:
```
console.log('%O', Number)
```
#### Clear the console
`console.clear()` clears the console (the behavior might depend on the console used)
#### Counting elements
`console.count()` is a handy method.
Take this code:
```
const x = 1
const y = 2
const z = 3
console.count(
'The value of x is ' + x + ' and has been checked .. how many times?'
)
console.count(
'The value of x is ' + x + ' and has been checked .. how many times?'
)
console.count(
'The value of y is ' + y + ' and has been checked .. how many times?'
)
```
What happens is that `count` will count the number of times a string is printed, and print the count next to it.
You can just count apples and oranges:
```
const oranges = ['orange', 'orange']
const apples = ['just one apple']
oranges.forEach(fruit => {
console.count(fruit)
})
apples.forEach(fruit => {
console.count(fruit)
})
```
#### Print the stack trace
There might be cases where it’s useful to print the call stack trace of a function, maybe to answer the question: “How did you reach that part of the code?”
You can do so using `console.trace()`:
```
const function2 = () => console.trace()
const function1 = () => function2()
function1()
```
This will print the stack trace. This is what’s printed if I try this in the Node REPL:
```
Trace
at function2 (repl:1:33)
at function1 (repl:1:25)
at repl:1:1
at ContextifyScript.Script.runInThisContext (vm.js:44:33)
at REPLServer.defaultEval (repl.js:239:29)
at bound (domain.js:301:14)
at REPLServer.runBound [as eval] (domain.js:314:12)
at REPLServer.onLine (repl.js:440:10)
at emitOne (events.js:120:20)
at REPLServer.emit (events.js:210:7)
```
#### Calculate the time spent
You can easily calculate how much time a function takes to run, using `time()`and `timeEnd()`
```
const doSomething = () => console.log('test')
const measureDoingSomething = () => {
console.time('doSomething()')
//do something, and measure the time it takes
doSomething()
console.timeEnd('doSomething()')
}
measureDoingSomething()
```
#### stdout and stderr
As we saw console.log is great for printing messages in the Console. This is what’s called the standard output, or `stdout`.
`console.error` prints to the `stderr` stream.
It will not appear in the console, but it will appear in the error log.
#### Color the output
You can color the output of your text in the console by using escape sequences. An escape sequence is a set of characters that identifies a color.
Example:
```
console.log('\x1b[33m%s\x1b[0m', 'hi!')
```
You can try that in the Node REPL, and it will print `hi!` in yellow.
However, this is the low-level way to do this. The simplest way to go about coloring the console output is by using a library. [Chalk](https://github.com/chalk/chalk) is such a library, and in addition to coloring it also helps with other styling facilities, like making text bold, italic or underlined.
You install it with `npm install chalk`, then you can use it:
```
const chalk = require('chalk')
console.log(chalk.yellow('hi!'))
```
Using `chalk.yellow` is much more convenient than trying to remember the escape codes, and the code is much more readable.
Check the project link I posted above for more usage examples.
#### Create a progress bar
[Progress](https://www.npmjs.com/package/progress) is an awesome package to create a progress bar in the console. Install it using `npm install progress`.
This snippet creates a 10-step progress bar, and every 100 ms one step is completed. When the bar completes we clear the interval:
```
const ProgressBar = require('progress')
const bar = new ProgressBar(':bar', { total: 10 })
const timer = setInterval(() => {
bar.tick()
if (bar.complete) {
clearInterval(timer)
}
}, 100)
```
### Accept input from the command line in Node.js
How to make a Node.js CLI program interactive?
Node since version 7 provides the `readline` [module](https://nodejs.org/api/readline.html) to perform exactly this: get input from a readable stream such as the `process.stdin` stream, which during the execution of a Node program is the terminal input, one line at a time.
```
const readline = require('readline').createInterface({
input: process.stdin,
output: process.stdout
})
readline.question(`What's your name?`, (name) => {
console.log(`Hi ${name}!`)
readline.close()
})
```
This piece of code asks the username, and once the text is entered and the user presses enter, we send a greeting.
The `question()` method shows the first parameter (a question) and waits for the user input. It calls the callback function once enter is pressed.
In this callback function, we close the readline interface.
`readline` offers several other methods, and I’ll let you check them out on the package documentation I linked above.
If you need to require a password, it’s best to now echo it back, but instead showing a `*`symbol.
The simplest way is to use the readline-sync [package](https://www.npmjs.com/package/readline-sync) which is very similar in terms of the API and handles this out of the box.
A more complete and abstract solution is provided by the [Inquirer.js package](https://github.com/SBoudrias/Inquirer.js).
You can install it using `npm install inquirer`, and then you can replicate the above code like this:
```
const inquirer = require('inquirer')
var questions = [{
type: 'input',
name: 'name',
message: "What's your name?",
}]
inquirer.prompt(questions).then(answers => {
console.log(`Hi ${answers['name']}!`)
})
```
Inquirer.js lets you do many things like asking multiple choices, having radio buttons, confirmations, and more.
It’s worth knowing all the alternatives, especially the built-in ones provided by Node.js, but if you plan to take CLI input to the next level, Inquirer.js is an optimal choice.
### Expose functionality from a Node.js file using exports
How to use the `module.exports` API to expose data to other files in your application, or to other applications as well
Node.js has a built-in module system.