<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Kashyap Patel</title>
    <description>The latest articles on Forem by Kashyap Patel (@khpatel4991).</description>
    <link>https://forem.com/khpatel4991</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F7604%2F6532483.jpeg</url>
      <title>Forem: Kashyap Patel</title>
      <link>https://forem.com/khpatel4991</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/khpatel4991"/>
    <language>en</language>
    <item>
      <title>Node Fundamentals: Modules</title>
      <dc:creator>Kashyap Patel</dc:creator>
      <pubDate>Wed, 08 Apr 2020 04:56:25 +0000</pubDate>
      <link>https://forem.com/khpatel4991/node-fundamentals-modules-1o9o</link>
      <guid>https://forem.com/khpatel4991/node-fundamentals-modules-1o9o</guid>
      <description>&lt;p&gt;This is a series of posts that will illustrate the what, why and how of Node. I'll be sharing my learnings from a course on Advanced NodeJS by Samer Buna offered on &lt;a href="https://www.pluralsight.com"&gt;PluralSight&lt;/a&gt;. Any code samples tagged or attached will be available at the following repo. &lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vJ70wriM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/github-logo-ba8488d21cd8ee1fee097b8410db9deaa41d0ca30b004c0c63de0a479114156f.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/jscomplete"&gt;
        jscomplete
      &lt;/a&gt; / &lt;a href="https://github.com/jscomplete/advanced-nodejs"&gt;
        advanced-nodejs
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      For help, ask in #questions at slack.jscomplete.com
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  Node Modules
&lt;/h2&gt;

&lt;p&gt;Modularity is a first-class concept in Node.&lt;/p&gt;

&lt;p&gt;There are two core modules involved.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;require - It is a global function, but each module gets its own &lt;code&gt;require&lt;/code&gt; function&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;module - It is also available globally and is used to manage all the modules we require with &lt;code&gt;require&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Requiring a module in node is very simple concept.&lt;/p&gt;

&lt;p&gt;To execute a &lt;code&gt;require&lt;/code&gt; call, node goes through a following sequence of steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Resolving: Find the absolute file path of the module required.&lt;/li&gt;
&lt;li&gt;Loading: Determined by the content of the file at the resolved path.&lt;/li&gt;
&lt;li&gt;Wrapping: Gives every module its &lt;code&gt;private scope&lt;/code&gt; and what makes &lt;code&gt;require&lt;/code&gt; local to every module.&lt;/li&gt;
&lt;li&gt;Evaluating: Eventually, VM does something to code.&lt;/li&gt;
&lt;li&gt;Caching: When we require again, we don't go over all steps above mentioned.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;module&lt;/code&gt; Object
&lt;/h2&gt;

&lt;p&gt;Some interesting properties:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;id: String Identifier, Usually full path to the module except for the root module. &lt;code&gt;.&lt;/code&gt; identifier is used for the root module.&lt;/li&gt;
&lt;li&gt;filename: String path to the file containing the module. So when you require a module from &lt;code&gt;node_modules&lt;/code&gt;, it loads the content of a file into memory.&lt;/li&gt;
&lt;li&gt;path: Array of paths that will used to find a module that is required. It starts with &lt;code&gt;node_modules&lt;/code&gt; folder in current directory and goes all the way to the root directory. If it can't find a module in any of those directories, it will throw a &lt;code&gt;Cannot find module 'module'&lt;/code&gt; error. 
Core node modules are an exception. When you require a core node module, it resolves immediately.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's consider following example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ./index.js&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;In ./index.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;find-me&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// ./node_modules/find-me.js&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;In find-me.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This will result in output&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;In ./index.js
In find-me.js
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Note, not only it loads the file, it also evaluates when you require it.&lt;/p&gt;

&lt;p&gt;If you only want to load a file, and not evaluate it, you can use &lt;code&gt;require.resolve(package)&lt;/code&gt;. It will also throw an error if it can't find the package in any of the paths. This is used to determine if an optional package is installed or not.&lt;/p&gt;

&lt;p&gt;If you have &lt;code&gt;package&lt;/code&gt; installed in multiple folders present in &lt;code&gt;path&lt;/code&gt; property, it will only resolve the first one it finds.&lt;/p&gt;

&lt;p&gt;Usually, packages are not files, but are folders, with multiple files. It will use &lt;code&gt;index.js&lt;/code&gt; or &lt;code&gt;main&lt;/code&gt; property in &lt;code&gt;package.json&lt;/code&gt; of the package. We can require any module, with a relative or absolute path.&lt;/p&gt;

&lt;p&gt;Note &lt;code&gt;module&lt;/code&gt; object available in &lt;code&gt;index.js&lt;/code&gt; and in &lt;code&gt;package index.js&lt;/code&gt; are different. &lt;code&gt;module&lt;/code&gt; object in &lt;code&gt;package index.js&lt;/code&gt; will have a reference to root &lt;code&gt;index.js&lt;/code&gt;, and will be attached to it's &lt;code&gt;parent&lt;/code&gt; property.&lt;/p&gt;

&lt;h3&gt;
  
  
  Module Wrapper
&lt;/h3&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;js&lt;/span&gt;

&lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="c1"&gt;// this is ok&lt;/span&gt;
&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;// this is not ok&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;// this is ok, why?&lt;/span&gt;

&lt;span class="kd"&gt;var&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// local to this file&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Only the things we export are available outside the module. How come variables we declare are magically scope. The answer is simple.&lt;/p&gt;

&lt;p&gt;Before compiling a module, Node will wraps the module code in a function as follows.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; require('module').wrapper

(function (exports, require, module, __filename, __dirname) { ',
    '\n});

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This is how each module gets its own &lt;code&gt;require&lt;/code&gt;, &lt;code&gt;exports&lt;/code&gt; and &lt;code&gt;module&lt;/code&gt; object. These are just function arguments that are provided by wrapped function by node.&lt;/p&gt;

&lt;p&gt;To see the values of these arguments you can just run the following code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// index.js&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This will print all 5 arguments passed to the wrapper function.&lt;/p&gt;

&lt;p&gt;The wrapping function's return value is the &lt;code&gt;exports&lt;/code&gt; object reference. Note, &lt;code&gt;exports&lt;/code&gt; is just a variable reference to &lt;code&gt;module.exports&lt;/code&gt;. So, if we modify the whole of &lt;code&gt;exports&lt;/code&gt; by assignment operator, we lose the &lt;code&gt;module.exports&lt;/code&gt; module.&lt;/p&gt;

&lt;p&gt;So, there's nothing special about &lt;code&gt;require&lt;/code&gt; function. It takes the module name or path and returns the &lt;code&gt;exports&lt;/code&gt; object. So in test case scenarios, where one might need to overwrite/mock &lt;code&gt;require&lt;/code&gt;, we can do quite easily as follows.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="nx"&gt;require&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;mocked&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;somepackage&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;// { mocked: true }&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Let's say we have this simple function that takes an integer and a string and prints something.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// printStars.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;print&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;stars&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;header&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;*&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;stars&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;header&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;*&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;stars&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We want to run this function in two ways.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Through the command line as follows
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;node printStars.js 5 hello
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Through &lt;code&gt;require&lt;/code&gt; in another file as a module as follows.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// index.js&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;printStars&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;printStars&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hello&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;To achieve this, we can leverage wrapping. &lt;br&gt;
When it is run through Node CLI, &lt;code&gt;require.main&lt;/code&gt; will be the same as &lt;code&gt;module&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//printStars.js&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;print&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;stars&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;header&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;*&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;stars&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;header&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;*&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;stars&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;main&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// When run as script&lt;/span&gt;
  &lt;span class="nx"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// being required by other file&lt;/span&gt;
  &lt;span class="c1"&gt;// export the module&lt;/span&gt;
  &lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;print&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Caching
&lt;/h2&gt;

&lt;p&gt;Imagine this case&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// index.js&lt;/span&gt;

&lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;printFancy&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Prints&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Entry for `printFancy` module&lt;/span&gt;
&lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;printFancy&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Nothing happens &lt;/span&gt;

&lt;span class="c1"&gt;//printFancy.js&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello Fancy&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Note, when we require &lt;code&gt;printFancy&lt;/code&gt; first time, it will resolve, load, evaluate and cache the module. &lt;/p&gt;

&lt;p&gt;However, when we require again, node has cached the module and so will repeat earlier steps again.&lt;/p&gt;

&lt;p&gt;To circumvent this we can delete the cache on &lt;code&gt;require.cache&lt;/code&gt; object, before the second call, with &lt;code&gt;delete require.cache['absModulePath']&lt;/code&gt; and &lt;code&gt;printFancy&lt;/code&gt; will be called twice. But it is not the most efficient solution.&lt;/p&gt;

&lt;p&gt;The easiest solution is to wrap the &lt;code&gt;console log&lt;/code&gt; in &lt;code&gt;printFancy.js&lt;/code&gt; in a function and export it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// printFancy.js&lt;/span&gt;
&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello Fancy&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now every time you require the module, just execute the exports.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// index.js&lt;/span&gt;

&lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;printFancy&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)()&lt;/span&gt; &lt;span class="c1"&gt;// Prints &lt;/span&gt;
&lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;printFancy&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)()&lt;/span&gt; &lt;span class="c1"&gt;// Prints &lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



</description>
      <category>node</category>
      <category>javascript</category>
      <category>require</category>
    </item>
    <item>
      <title>Node Fundamentals: Buffer</title>
      <dc:creator>Kashyap Patel</dc:creator>
      <pubDate>Wed, 08 Apr 2020 04:44:21 +0000</pubDate>
      <link>https://forem.com/khpatel4991/node-fundamentals-buffer-3h8j</link>
      <guid>https://forem.com/khpatel4991/node-fundamentals-buffer-3h8j</guid>
      <description>&lt;p&gt;This is a series of posts that will illustrate the what, why and how of Node. I'll be sharing my learnings from a course on Advanced NodeJS by Samer Buna offered on &lt;a href="https://www.pluralsight.com"&gt;PluralSight&lt;/a&gt;. Any code samples tagged or attached will be available at the following repo. &lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vJ70wriM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/github-logo-ba8488d21cd8ee1fee097b8410db9deaa41d0ca30b004c0c63de0a479114156f.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/jscomplete"&gt;
        jscomplete
      &lt;/a&gt; / &lt;a href="https://github.com/jscomplete/advanced-nodejs"&gt;
        advanced-nodejs
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      For help, ask in #questions at slack.jscomplete.com
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;h1&gt;
  
  
  Buffer
&lt;/h1&gt;

&lt;p&gt;Buffer is heavily used in Node to work with binary streams of data. It is a low-level object to represent a sequence of binary data.&lt;/p&gt;

&lt;p&gt;A buffer is essentially a chunk of memory allocated &lt;em&gt;outside v8 heap&lt;/em&gt; and we can put some data in memory, which can be interpreted in many ways based on the length of each character. That's why there is always a corresponding &lt;em&gt;character-encoding&lt;/em&gt; associated with that buffer. &lt;/p&gt;

&lt;p&gt;Whatever we place inside a buffer, doesn't have any character encoding, so to read it we need to specify an encoding.&lt;/p&gt;

&lt;p&gt;Unlike arrays, once the buffer is allocated, it can't be resized. We can create a buffer in 1 of 3 major ways.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Buffer.alloc(n) - Allocates a 0-filed buffer of n bytes in memory.&lt;/li&gt;
&lt;li&gt;Buffer.allocUnsafe(n) - Allocates a buffer of n byte in memory. This can cause a vulnerability as it can contain sensitive information.&lt;/li&gt;
&lt;li&gt;Buffer.from() - Allocates a buffer with a value passed in argument.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;touché&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;buffer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Buffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;touché&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 6&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 7&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Buffers are useful when we want to read an image file from a TCP stream or a compressed file or any other form of binary data.&lt;/p&gt;

&lt;p&gt;Just like arrays and string, we can use operations like &lt;code&gt;includes&lt;/code&gt;, &lt;code&gt;slice&lt;/code&gt;, &lt;code&gt;indexOf&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In the case of &lt;code&gt;slice&lt;/code&gt;, unlike arrays, a sliced copy will use the same memory space.&lt;/p&gt;


&lt;div class="ltag__replit"&gt;
  &lt;iframe height="550px" src="https://repl.it/@khpatel4991/ClumsyQuarrelsomeMacro?lite=true"&gt;&lt;/iframe&gt;
&lt;/div&gt;



&lt;h2&gt;
  
  
  String Decoder
&lt;/h2&gt;

&lt;p&gt;When converting streams of binary data, use &lt;a href="https://nodejs.org/api/string_decoder.html"&gt;String Decoder&lt;/a&gt; module as it handles multi-byte characters much better. It gracefully handles incomplete characters, while calling &lt;code&gt;toString&lt;/code&gt; method on buffer doesn't do that.&lt;/p&gt;


&lt;div class="ltag__replit"&gt;
  &lt;iframe height="550px" src="https://repl.it/@khpatel4991/AwareIncompatibleWamp?lite=true"&gt;&lt;/iframe&gt;
&lt;/div&gt;


</description>
      <category>node</category>
      <category>javascript</category>
      <category>buffer</category>
    </item>
    <item>
      <title>Node Fundamentals: CLI and Repl</title>
      <dc:creator>Kashyap Patel</dc:creator>
      <pubDate>Wed, 08 Apr 2020 04:30:36 +0000</pubDate>
      <link>https://forem.com/khpatel4991/node-fundamentals-cli-and-repl-gfa</link>
      <guid>https://forem.com/khpatel4991/node-fundamentals-cli-and-repl-gfa</guid>
      <description>&lt;p&gt;This is a series of posts that will illustrate the what, why and how of Node. I'll be sharing my learnings from a course on Advanced NodeJS by Samer Buna offered on &lt;a href="https://www.pluralsight.com"&gt;PluralSight&lt;/a&gt;. Any code samples tagged or attached will be available at the following repo. &lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vJ70wriM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/github-logo-ba8488d21cd8ee1fee097b8410db9deaa41d0ca30b004c0c63de0a479114156f.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/jscomplete"&gt;
        jscomplete
      &lt;/a&gt; / &lt;a href="https://github.com/jscomplete/advanced-nodejs"&gt;
        advanced-nodejs
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      For help, ask in #questions at slack.jscomplete.com
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;h1&gt;
  
  
  Node CLI and REPL
&lt;/h1&gt;

&lt;p&gt;Node CLI comes with a variety of options to expose built-in debugging, multiple ways to execute scripts and other helpful runtime options.&lt;/p&gt;

&lt;p&gt;Running a &lt;code&gt;node&lt;/code&gt; command without any arguments starts a REPL.&lt;/p&gt;

&lt;p&gt;R - Read&lt;br&gt;
E - Eval&lt;br&gt;
P - Print&lt;br&gt;
L = Loop&lt;/p&gt;

&lt;p&gt;When in REPL, you hit enter, it reads the command, executes it, prints the result and waits for the next command.&lt;/p&gt;
&lt;h3&gt;
  
  
  Helpful CLI Tips and Tricks
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;-c&lt;/code&gt; - Syntax check&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-p&lt;/code&gt; - Print Command. e.g &lt;code&gt;node -p "process.argv.slice(1) test 42"&lt;/code&gt; will print ['test', '42']&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Helpful Repl Tricks and Tips
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Autocomplete by &lt;code&gt;Tab&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;rlwrap&lt;/code&gt; utility to track reverse search.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;NODE_NOREADLINE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1 rlwrap node
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;_&lt;/code&gt; is used to capture the last evaluated value.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Special commands that begin with a &lt;code&gt;dot&lt;/code&gt;. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;.help&lt;/code&gt; to print all such commands. &lt;/li&gt;
&lt;li&gt;
&lt;code&gt;.break&lt;/code&gt; to break out of a multiline session.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;.load&lt;/code&gt; to load external script file&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;.save&lt;/code&gt; to save current session&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You can create your own repl with custom options by requiring a &lt;code&gt;repl&lt;/code&gt; module and starting it with &lt;a href="https://nodejs.org/api/repl.html#repl_repl_start_options"&gt;custom options&lt;/a&gt;. You can also control repl's global context in case of preloading a library of data.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example below will start the repl in strict mode and doesn't print anything when result is &lt;code&gt;undefined&lt;/code&gt;. Also, it will have lodash available globally.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;repl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;repl&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;lodash&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;lodash&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;repl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;ignoreUndefined&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;replMode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;repl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;REPL_STRICT_MODE&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lodash&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;lodash&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



</description>
      <category>node</category>
      <category>javascript</category>
      <category>cli</category>
    </item>
    <item>
      <title>Node Fundamentals: Process</title>
      <dc:creator>Kashyap Patel</dc:creator>
      <pubDate>Wed, 08 Apr 2020 04:26:36 +0000</pubDate>
      <link>https://forem.com/khpatel4991/node-fundamentals-process-1fj6</link>
      <guid>https://forem.com/khpatel4991/node-fundamentals-process-1fj6</guid>
      <description>&lt;p&gt;This is a series of posts that will illustrate the what, why and how of Node. I'll be sharing my learnings from a course on Advanced NodeJS by Samer Buna offered on &lt;a href="https://www.pluralsight.com"&gt;PluralSight&lt;/a&gt;. Any code samples tagged or attached will be available at the following repo. &lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vJ70wriM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/github-logo-ba8488d21cd8ee1fee097b8410db9deaa41d0ca30b004c0c63de0a479114156f.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/jscomplete"&gt;
        jscomplete
      &lt;/a&gt; / &lt;a href="https://github.com/jscomplete/advanced-nodejs"&gt;
        advanced-nodejs
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      For help, ask in #questions at slack.jscomplete.com
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;h1&gt;
  
  
  &lt;code&gt;process&lt;/code&gt; Object
&lt;/h1&gt;

&lt;p&gt;&lt;code&gt;process&lt;/code&gt; object provides a bridge between a Node application and its running environment.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;process&lt;/code&gt; object is an instance of event-emitter. So we can emit and listen to events on the object&lt;/p&gt;

&lt;h2&gt;
  
  
  Useful properties and events
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;pid: Outputs the process id on OS level.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;version: Read dependencies and versions&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;node &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s2"&gt;"process.version"&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;
  node: &lt;span class="s1"&gt;'13.12.0'&lt;/span&gt;,
  v8: &lt;span class="s1"&gt;'7.9.317.25-node.30'&lt;/span&gt;,
  uv: &lt;span class="s1"&gt;'1.35.0'&lt;/span&gt;,
  zlib: &lt;span class="s1"&gt;'1.2.11'&lt;/span&gt;,
  brotli: &lt;span class="s1"&gt;'1.0.7'&lt;/span&gt;,
  ares: &lt;span class="s1"&gt;'1.16.0'&lt;/span&gt;,
  modules: &lt;span class="s1"&gt;'79'&lt;/span&gt;,
  nghttp2: &lt;span class="s1"&gt;'1.40.0'&lt;/span&gt;,
  napi: &lt;span class="s1"&gt;'6'&lt;/span&gt;,
  llhttp: &lt;span class="s1"&gt;'2.0.4'&lt;/span&gt;,
  openssl: &lt;span class="s1"&gt;'1.1.1e'&lt;/span&gt;,
  cldr: &lt;span class="s1"&gt;'36.1'&lt;/span&gt;,
  icu: &lt;span class="s1"&gt;'66.1'&lt;/span&gt;,
  tz: &lt;span class="s1"&gt;'2019c'&lt;/span&gt;,
  unicode: &lt;span class="s1"&gt;'13.0'&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;env - Lists all environment variables. Better to always read values from a layer above it using &lt;code&gt;config&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;release.lts - &lt;code&gt;node -p "process.release.lts"&lt;/code&gt; will be undefined if not on LTS version of node.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;exit&lt;/code&gt; event - Will be invoked when the application has nothing else to do or a manual &lt;code&gt;process.exit&lt;/code&gt; call is made.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;exit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// do one final synchronous operation&lt;/span&gt;
  &lt;span class="c1"&gt;// before node process terminates.&lt;/span&gt;
  &lt;span class="c1"&gt;// can't stop termination at this point&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;uncaughtException&lt;/code&gt; event - Will invoke when an error is not caught in the application. If not registered, node will print the stack trace and terminate. When it is registered, node will not terminate and will stay in an unstable state. It's better to forcefully terminate the process when this event is invoked.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;uncaughtException&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// something wnet unhandled&lt;/span&gt;
  &lt;span class="c1"&gt;// Do any cleanup and EXIT forcefully.&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



</description>
      <category>node</category>
      <category>javascript</category>
      <category>process</category>
    </item>
    <item>
      <title>Node Fundamentals: Architecture</title>
      <dc:creator>Kashyap Patel</dc:creator>
      <pubDate>Wed, 08 Apr 2020 04:15:07 +0000</pubDate>
      <link>https://forem.com/khpatel4991/node-fundamentals-architecture-2p3f</link>
      <guid>https://forem.com/khpatel4991/node-fundamentals-architecture-2p3f</guid>
      <description>&lt;p&gt;This is a series of posts that will illustrate the what, why and how of Node. I'll be sharing my learnings from a course on Advanced NodeJS by Samer Buna offered on &lt;a href="https://www.pluralsight.com"&gt;PluralSight&lt;/a&gt;. Any code samples tagged or attached will be available at the following repo. &lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vJ70wriM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/github-logo-ba8488d21cd8ee1fee097b8410db9deaa41d0ca30b004c0c63de0a479114156f.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/jscomplete"&gt;
        jscomplete
      &lt;/a&gt; / &lt;a href="https://github.com/jscomplete/advanced-nodejs"&gt;
        advanced-nodejs
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      For help, ask in #questions at slack.jscomplete.com
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;h3&gt;
  
  
  Node VM
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;v8, Default, Single-Threaded&lt;/li&gt;
&lt;li&gt;Chakra by Microsoft, powers Edge browser&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;VM executes the Javascript code. So, v8 actually executes your JS code when you run a node application.&lt;/p&gt;

&lt;h3&gt;
  
  
  v8 Feature Groups
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Shipping - Available by default&lt;/li&gt;
&lt;li&gt;Staged - Not quite ready yet. flag &lt;code&gt;--harmony&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;In-Progress - Less stable.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can see the list of all group features by&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;node&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nx"&gt;v8&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;grep&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;in progress&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="nx"&gt;node&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nx"&gt;v8&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;grep&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;staged&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Overview
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--i_v2SgCQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/7kwwi4ara0xwaveh8w7l.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--i_v2SgCQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/7kwwi4ara0xwaveh8w7l.jpg" alt="Node Architecture"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Node is more than a wrapper for v8, it provides APIs for working with the file system, operating system, binary data, networking and much more. It mainly constitutes of the following components.&lt;/p&gt;

&lt;h4&gt;
  
  
  v8
&lt;/h4&gt;

&lt;p&gt;Node v8 uses v8 C++ API. So, node API eventually executes C++ code using V8 object and function templates.&lt;/p&gt;

&lt;p&gt;When node is done waiting for IO or timers, it usually has callback functions to invoke back to. When it's time to invoke these callbacks, node passes control from &lt;code&gt;libuv&lt;/code&gt; to the v8 engine. When v8 executes the callback, it passes control to Node itself. &lt;/p&gt;

&lt;p&gt;When control is with v8, Node can not execute any Javascript code as v8 is &lt;em&gt;single-threaded&lt;/em&gt;. Node will simply wait until v8 is ready for more operations. &lt;/p&gt;

&lt;p&gt;This is actually programming in node so simple yet powerful as we don't have to worry about locks or race conditions. There is only one thread where our Javascript code runs.&lt;/p&gt;

&lt;h4&gt;
  
  
  libuv
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;libuv&lt;/code&gt; is a C library developed for Node, but now it's used by Rust, Julia and others. It's used to abstract the non-blocking I/O operations. It provides a consistent interface across many operating systems. &lt;/p&gt;

&lt;p&gt;It handles operations on the file system, TCP/UDP sockets, child processes, and others. &lt;code&gt;libuv&lt;/code&gt; includes a thread pool to handle what can't be done asynchronously at OS level. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;libuv&lt;/code&gt; also provides node with Event Loop.&lt;/p&gt;

&lt;h4&gt;
  
  
  More Dependencies
&lt;/h4&gt;

&lt;p&gt;Apart from v8 and libuv, node has a few more dependencies.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;http-parser: Library for parsing HTTP messages. It works for requests and responses, works with a very small memory footprint.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;c-ares: Enables performing asynchronous DNS queries.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenSSL: Mostly used in &lt;code&gt;tls&lt;/code&gt; and &lt;code&gt;crypto&lt;/code&gt; modules. Provides the implementation for many cryptographic functions&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;zlib: Used for fast streaming compression and decompression interfaces.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>node</category>
      <category>javascript</category>
      <category>v8</category>
    </item>
    <item>
      <title>End to End Testing with Cypress</title>
      <dc:creator>Kashyap Patel</dc:creator>
      <pubDate>Wed, 26 Jun 2019 22:47:05 +0000</pubDate>
      <link>https://forem.com/khpatel4991/end-to-end-testing-with-cypress-203f</link>
      <guid>https://forem.com/khpatel4991/end-to-end-testing-with-cypress-203f</guid>
      <description>&lt;p&gt;End-to-end testing lets us test our whole application from start to finish. It involves ensuring that all the integrated pieces of an application function and work together as expected. E2E tests simulate real user scenarios, essentially testing how a real user would use the application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Selenium
&lt;/h2&gt;

&lt;p&gt;Selenium is an application written in Java that lets us test our apps from the point of view of a browser. It’s a little bit old but lets us do a lot of wonderful things that we might not otherwise be able to do with a nice ecosystem of integration tools.&lt;/p&gt;

&lt;p&gt;Here’s how it works, Selenium has a Java Service that listens for commands. You write test code in any language, which then uses a library to speak the language of Selenium called “webdriver API” and send these commands to the service. The service then queues all these commands and tries to send them to any given browser, the real browsers where tests are being executed.&lt;/p&gt;

&lt;p&gt;Unfortunately, there are a number of different abstractions, integrations, and interfaces where things could go wrong. When a test fails, it could be any one of these issues:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Our test code has an issue&lt;/li&gt;
&lt;li&gt;Platform dependent API that works with Selenium might be behaving differently&lt;/li&gt;
&lt;li&gt;A different version of Selenium might work differently based on the usage&lt;/li&gt;
&lt;li&gt;Things could go wrong in Java service&lt;/li&gt;
&lt;li&gt;Browser web driver can have bugs, Message multiplexing can go wrong if socket connection to browser goes haywire resulting in funny front-end behaviors&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are a lot of places where things can go wrong with this architecture. Plus the damn thing is SLOW.&lt;/p&gt;

&lt;p&gt;We, humans, have good intuition skills, but computers and code do not. When our test code is running, it does exactly what it is told to do without taking any guesses. And if it clicks a button and starts to re-render, we need to be very careful about knowing whether it finished rendering before we try to do the next thing. Any slowness in asynchronous services like DB, network, disk read/writes can break the order of the tests to be executed, which can cause a cascading failure of tests.&lt;/p&gt;

&lt;p&gt;When we take this heavy architecture and try to merge with our apps, things get extra juicy. It’s a recipe for frustration. We’d write a commit, run tests locally, everything looks good, we’d push it to the build and, alas, some test would fail. Then we’d run that test again, as it’s not something the commit should have broken, and it would pass! Hurrah!&lt;/p&gt;

&lt;p&gt;Our app should be simple, fast and consistent. Right? Our pages make complex interaction to provide rich user experience consistently so our users can trust our service more which leads to increased user retention and returns.&lt;/p&gt;

&lt;p&gt;Overall, Selenium is an extremely popular piece of software that has become the basis of many automation strategies. It comes with an excellent community, support, and tools, and allows us to do cross-browser testing. However, it comes with its limitations. Can we do better?&lt;/p&gt;

&lt;h2&gt;
  
  
  Cypress
&lt;/h2&gt;

&lt;p&gt;Welcome Cypress! Cypress is an OSS written in Javascript which lets us write E2E tests like Selenium. At &lt;a href="https://perfecttense.com" rel="noopener noreferrer"&gt;PerfectTense&lt;/a&gt; we have E2E tests for dreaded &lt;code&gt;contenteditable&lt;/code&gt;. I chose not to use Selenium due to its setup process and I had a general impression of it being slow and brittle. In contrast, Cypress can be started with two simple commands, and running tests is simple. When I first ran Cypress, my mind was blown by the speed at which sample tests ran. Cypress also creates several E2E tests when it starts for the very first time. These are helpful guidelines on what, why and how to test and how to use. They are also great for learning how to use their APIs to visit a page, find and interact with an element, deal with cookies, ajax requests, and more.&lt;/p&gt;

&lt;p&gt;What makes Cypress different, is that is built on a new architecture that eliminates flakiness. It’s able to achieve by running in the same run-loop as your application whereas Selenium executes remote commands through a network. It works with any server-rendered pages (like our HAML pages) or a web app written in any modern framework like React, Vue, etc.&lt;/p&gt;

&lt;p&gt;Cypress tests are written in Javascript with familiar matchers from Mocha, Chai, and Sinon. They are executed in the same environment of the browser itself and require no special setup, language or driver bindings. JS to rule them all.&lt;/p&gt;

&lt;p&gt;Because of no network latency and no need for any setup, Cypress runs extremely fast. You can actually do TDD with full end-to-end tests for the very first time. You can develop faster while driving the entire dev process with tests because you can see your application, you have access to the developer tools, you have access to server-side code, and changes are reflected in real time. It’s so fast, it’ll let you find bugs you didn’t know existed.&lt;/p&gt;

&lt;p&gt;Here is a comparison of timings of tests written in Cypress and Capybara that visit the same page, perform the same actions with the DOM and have the same expectations in the end.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Flbej5d6646c4qer93sa5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Flbej5d6646c4qer93sa5.png" alt="Comparison Benchmark"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Some other useful, nice-to-have features and benefits that Cypress provides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reliably test viewport and scroll behaviors.&lt;/li&gt;
&lt;li&gt;Replay DOM snapshots and walk through our tests.&lt;/li&gt;
&lt;li&gt;Built-in test runner with a web UI to run any test individually or all together.&lt;/li&gt;
&lt;li&gt;Easily pause and debug in between expectations.&lt;/li&gt;
&lt;li&gt;Browser screenshots are taken automatically on failure, a video is recorded of your entire test suite when tests are run from the CLI.&lt;/li&gt;
&lt;li&gt;Actual &lt;code&gt;window&lt;/code&gt; object from the browser to expect messages sent to globals.&lt;/li&gt;
&lt;li&gt;AGAIN It’s blazing fast. Our tests in cypress run 3–4x faster compared to Selenium Webdriver.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Current Limitations
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Only works with Chromium-based browsers and tests can only to be written in Javascript. Cypress team has been actively working on making it compatible for other browsers. You can track the progress &lt;a href="https://github.com/cypress-io/cypress/issues/3207" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Testing iframes requires some workarounds but it's certainly possible.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To summarize, Cypress is still a new tool with a growing community, a unique architecture that manipulates DOM fast and reliably without any network latency, and is built with developer-friendliness in mind. It also has excellent documentation, with a lot of snippets that can help us write more manageable tests and stick to best practices.&lt;/p&gt;

&lt;p&gt;Hope this helped!&lt;/p&gt;

&lt;h2&gt;
  
  
  Further Readings:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.cypress.io/guides/overview/why-cypress.html#In-a-nutshell" rel="noopener noreferrer"&gt;Why Cypress&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>testing</category>
      <category>e2e</category>
      <category>cypress</category>
      <category>selenium</category>
    </item>
  </channel>
</rss>
